Ext.Links
-Lang&VM specs
-API
-Adpot OpenJDK prebuilt binaries
https://hg.openjdk.java.net/jdk/jdk
-OpenJDK@Mercurial
- @[https://wiki.openjdk.java.net/]
- @[https://openjdk.java.net/]

-JAVA MIND-MAP
-(Active) Java JVM List
-Eclipe Tools for [QA]
-Excellent Java Blog (spanish)
-JAVA Enhancements proposals
-Douglas Craigs Schmidt Java Lessons:
-Awesome Java
Who-is-Who
(Forcibly incomplete but still quite pertinent list of core developers and companies)
- James Arthur Gosling:  Founder and lead-designer of the Java Programming Language
  @[https://en.wikipedia.org/wiki/James_Gosling]

- Joshua J. Bloch:
  @[https://en.wikipedia.org/wiki/Joshua_Bloch]
  - Author of the book "Effective Java" (a must read)
    and co-author of two other books:
    - Java Puzzlers (2005)
    - Java Concurrency in Practice (2006)
  - Led the design and implementation of numerous
    Java platform features, including the
    Java Collections Framework, the java.math package,
    and the assert mechanism.

- Julien Viet:
 @[http://www.julienviet.com/]
  Core developer of VertX, crash (http://www.crashub.org/),
  and many other interesting Java software.
  @[https://github.com/vietj?utf8=%E2%9C%93&tab=repositories&q=&type=source]

- Ben Evans:
  - jClarity Co-founder.
  - Java Champion, author, speaker, consultant
  - voting member on Java’s governing
  - Author of 5 books
    - “The Well-Grounded Java Developer”,
    - new editions of “Java in a Nutshell”,
    - “Java: The Legend” and “Optimizing Java”.
    - Track lead for Java / JVM at InfoQ.
  @[https://www.jbcnconf.com/2019/infoTalk.html?id=5c64983638da16483151bb37]
  IMPLEMENTING A SIMPLE JVM IN JAVA AND RUST
  ... I will explain how we might start to implement a JVM from scratch.. then
   we will show how the Rust programming language provides a good alternative
   implementation language for our simple JVM. We will showcase some basic Rust
   language features and show how they can be used to provide a version of our
   JVM that is much cleaner and easier to understand, even if you've never
   seen Rust code before!"""

- Emmanuel Bernard: Distinguished Engineer and Chief Architect Data at
  Red Hat (middleware). His work is Open Source. He is most well known for his
  contributions and lead of the Hibernate projects as well as his contribution
  to Java standards. His most recent endeavour is Quarkus (A Kubernetes Native
  Java stack tailored for GraalVM and OpenJDK HotSpot, crafted from the best of
  breed Java libraries and standards).

- https://community.oracle.com/community/groundbreakers/java/java-champions
- https://blogs.oracle.com/java/new-java-champions-in-2017
Inside the JVM
@[https://www.artima.com/insidejvm/ed2/index.html]
Memory
  JVM MEMORY
(REF)
JAVA MEMORY MODEL:

         │    STACK ("SMALL")          │ HEAP  ("HUGE")
         │ private to each Thread      │ Shared by Threads
─────────┼─────────────────────────────┼──────────────────
Contain  │ - references to heap objects│ - objects
         │ - value types               │ - instance fields
         │ - formal method params      │ - static fields
         │ - exception handler params  │ - array elements

* 1: Ref(erence) types on the stack point to real object in HEAP memory.

Reference Types regarding how the object on the heap is eligible for garbage collection
┌─────────┬───────────────────────────────────────────────────────────────────────────
│ STRONG  │ - Most popular.
│         │ - The object on the heap it is not garbage collected
│         │   while there is a strong reference pointing to it, or if it is
│         │   strongly reachable through a chain of strong references.
├─────────┼───────────────────────────────────────────────────────────────────────────
│ WEAK    │ - most likely to not survive after the next garbage collection process.
│         │ - Is created like
│         │    WeakReference˂StringBuilder˃ reference =
│         │     = new WeakReference˂˃(new StringBuilder());
│         │ - ºEx.use case: caching:º
│         │   We let the GC remove the object pointed to by the weak reference,
│         │   after which a null will be returned
│         │   See JDK implementation at
│         │   @[https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html]
├─────────┼───────────────────────────────────────────────────────────────────────────
│ SOFT    │ - used for more memory-sensitive scenarios
│         │ - Will be garbage collected only when the application is running low on memory.
│         │ - *Java guarantees that all soft referenced objects
│         │   are cleaned up before throwing OutOfMemoryError*
│         │ - is created as follows:
│         │   SoftReference˂StringBuilder˃ reference = new SoftReference˂˃(new StringBuilder());
├─────────┼───────────────────────────────────────────────────────────────────────────
│ PHANTOM │ - Used to schedule post-mortem cleanup actions, since we know for
│         │   sure that objects are no longer alive.
│         │ - Used only with a reference queue, since the .get() method of
│         │   such references will always return null.
│         │ - ºThese types of references are considered preferable to finalizersº
└─────────┴───────────────────────────────────────────────────────────────────────────
Force
string pool
reuse
- Strings are immutable.
- Stored on the heap
- Java manages a string pool in memory,
  reusing strings whenever possible.

String string01 = "297",                                string01 == string02 : true
       string02 = "297",                                string01 == string03 : Rºfalseº *1
       string03 = new Integer(297).toString(),          string01 == string04 : true  *2
       string04 = new Integer(297).toString()º.intern()º; *2

º1: RºPool reuse does not work for dynamically created strings*
*2: If we consider that the computed String will be used quite often,
    we can force the JVM to add it to the string pool by adding the
    .intern() method at the end of computed string:
"MARK&SWEEP"
JVM analyzes the variables from the stack and "marks" all the objects that need to be kept alive.
Then, all the unused objects are cleaned up.

The more garbage there is, and the fewer that objects are marked alive, the faster the process is.

To optimize even more heap memory actually consists of multiple parts (Java 8+):

HEAP     |
SPACES   |
---------+-------------------------------------
Eden     | - object are place here upon creation.
         | - "small" -→ gets full quite fast.
         | - GC runs on the Eden space and marks objects as alive
---------+-------------------------------------
S0       | - Eden Objects surviving 1st GC are moved here
         |
---------+-------------------------------------
S1       | - Eden Objects surviving 2nd GC are moved here
         | - S0   Objects surviving     GC are moved here
---------+-------------------------------------
Old      | - Object survives for "N" rounds of GC (N depends on implementation),
         |   most likely that it will survive forever, and get moved here
         | - Bigger than Eden and S0,S1. GC doesn't run so often
---------+-------------------------------------
Metaspace| - metadata about loaded classes
         | (PermGen Before Java 8)
---------+-------------------------------------
String   |
  pool   |
---------+-------------------------------------
GC Types
- default GC type is based on the underlying hardware
- programmer can choose which one should be used


   GC TYPE     | Description  / Use-Cases
+--------------+-----------------------------------------------------------------------------
|Serial GC     | - Single thread collector.
|              | - ºHalt all app threads while executingº
|              | - Mostly applies to ºsmall apps with small data usageº
|              | - Can be enabled through : Oº-XX:+UseSerialGCº
+--------------+-----------------------------------------------------------------------------
|Parallel GC   | - Multiple threads used for GC
|              | - ºHalt all app threads while executingº
|              | - Also known as throughput collector
|              | - Can be enabled through : Oº-XX:+UseParallelGCº
+--------------+-----------------------------------------------------------------------------
|Mostly        | - works concurrent to the application, "mostly" not halting threads
|Concurrent GC | - "mostly": There is a period of time for which the threads are paused.
|              |    Still, the pause is kept as short as possible to achieve the best GC performance.
|              | - 2 types of mostly concurrent GCs:
|              |   * Garbage First - high throughput with a reasonable application pause time.
|              |                   - Enabled with the option: Oº-XX:+UseG1GCº
|              |   º Concurrent Mark Sweep: app pause is kept to minimum. ºDeprecated as Java9+*
|              |                   - Enabled with the option: Oº-XX:+UseConcMarkSweepGCº
+--------------+-----------------------------------------------------------------------------
Optimization Tips
- To minimize the memory footprint, limit the scope of the variables as much as possible.

- Explicitly refer to null obsolete references making them eligible for GC.

- Avoid finalizers. They slow down the process and they do not guarantee anything.
  Prefer phantom references for cleanup work.

- Do not use strong references where weak or soft references apply.
 ºThe most common memory pitfalls are caching scenarios,when dataº
 ºis held in memory even if it might not be needed.º

- Explicitly specify heap size for the JVM when running the application:
  -  allocate a reasonable initial and maximum amount of memory for the heap.
   OºInitial heap size -Xms512m º – set initial heap     size to  512 megabytes
   OºMaximum heap size -Xmx1024mº – set maximum heap     size to 1024 megabytes
   OºThread stack size -Xss128m º – set thread stack     size to  128 megabytes
   OºYoung genera.size -Xmn256m º – set young generation size to  256 megabytes


- If app OutOfMemoryError-crashes, extra info about memory leak can be obtained through
  Oº–XX:HeapDumpOnOutOfMemoryº, creating a heap dump file

- Use Oº-verbose:gcº to get the garbage collection output.

- Eclipse Memory Analyzer Manual:
@[https://help.eclipse.org/2019-06/index.jsp?topic=%2Forg.eclipse.mat.ui.help%2Fwelcome.html&cp=62]
Profiling:
JVisualVM (standard on the JDK) displays memory usage and other useful things:
- The only thing you have to do is install a plugin named Visual GC,
  which allows you to see how the memory is actually structured.
- JVisualVM also has the functionality to make a heap dump at a certain point,
 so you could analyze, per class, how much memory it occupies.
String
final String formatedNumber = String.format("%4d",100);
See also: [[Format String Checker?]]
java.time
java.time.*
- JDK 1.8+
- "deprecates" java.util.(Date|Calendar|TimeZome)
- All the classes are IMMUTABLE and THREAD-SAFE
Oºimport java.time.Instant;º
Oºimport java.time.ZonedDateTime;º
Oºimport java.time.ZoneId;º
Oºimport java.util.concurrent.TimeUnit;º
...
OºInstantºBºtimestampº = OºInstantº.now();              // Create from system clock
          Bºtimestampº.plus(Duration.ofSeconds(10));    // Add 10 seconds

  │OºInstantº to String                 │ OºInstantº from String
  │(format with time-zone)              │ (parse string)
  ├─────────────────────────────────────┼───────────────────────────────────────────────────
  │OºZonedDateTimeº zdt1 =              │
  │     OºZonedDateTimeº.of             │ String sExpiresAt="2013-05-30T23:38:23.085Z";
  │       (                             │ OºZonedDateTimeºzdt2 = OºZonedDateTimeº.parse(sExpiresAt);
  │         2017, 6, 30           ,     │
  │         1, 2, 3               ,     │ OºInstantºi1 = OºInstantº.from(zdt1),
  │         (int) TimeUnit.             │           i2 = OºInstantº.from(zdt2);
  │               MILLISECONDS.         │
  │               toNanos(100),         │
  │         ZoneId.of("Europe/Paris")   │
  │       );          ^^^               │
  │     Ex: "Z","-02:00","Asia/Tokyo",..│
  │String s1 = zdt1.toString();         │
          ^^
  2017-06-30T01:02:03.100+02:00[Europe/Madrid]

java.text.DateFormat:
date  (none)           DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
      short            DateFormat.getDateInstance(DateFormat.SHORT, getLocale())
      medium           DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
      long             DateFormat.getDateInstance(DateFormat.LONG, getLocale())
      full             DateFormat.getDateInstance(DateFormat.FULL, getLocale())
      SubformatPattern new SimpleDateFormat(subformatPattern, getLocale())

time  (none)           DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
      short            DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())
      medium           DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
      long             DateFormat.getTimeInstance(DateFormat.LONG, getLocale())
      full             DateFormat.getTimeInstance(DateFormat.FULL, getLocale())
      SubformatPattern new SimpleDateFormat(subformatPattern, getLocale())

ºCompatibility with Java ˂=1.7º
- (java.util.) Date, Calendar and TimeZone
  "buggy" classes/subclasses were used.
  ^^^^^^^
  - Calendar class was NOT type safe
  - Mutable non-threadsafe classes
  - Favored programming errors
    (unusual numbering of months,..)

- Next compatibility conversion methods were added in 1.8:
  - Calendar.toInstant()
  - GregorianCalendar.toZonedDateTime()
  - GregorianCalendar.from(ZonedDateTime) (Using default local)
  - Date.from(Instant)
  - Date.toInstant()
  - TimeZone.toZoneId()

ºjava.time. Package summaryº
                   Description
-----------------------------------------------------------------------------------
Clock              A clock providing access to the current instant, date and
                   time using a time-zone.
-----------------------------------------------------------------------------------
Duration           A time-based amount of time, such as '34.5 seconds'.
-----------------------------------------------------------------------------------
Instant            An instantaneous point on the time-line.
-----------------------------------------------------------------------------------
LocalDate          A date without a time-zone in the ISO-8601 calendar system,
                   such as 2007-12-03.
-----------------------------------------------------------------------------------
LocalDateTime      A date-time without a time-zone in the ISO-8601 calendar
                   system, such as 2007-12-03T10:15:30.
-----------------------------------------------------------------------------------
LocalTime          A time without a time-zone in the ISO-8601 calendar system,
                   such as 10:15:30.
-----------------------------------------------------------------------------------
MonthDay           A month-day in the ISO-8601 calendar system, such as --12-03.
-----------------------------------------------------------------------------------
OffsetDateTime     A date-time with an offset from UTC/Greenwich in the ISO-8601
                   calendar system, such as 2007-12-03T10:15:30+01:00.
-----------------------------------------------------------------------------------
OffsetTime         A time with an offset from UTC/Greenwich in the ISO-8601
                   calendar system, such as 10:15:30+01:00.
-----------------------------------------------------------------------------------
Period             A date-based amount of time in the ISO-8601 calendar system,
                    such as '2 years, 3 months and 4 days'.
-----------------------------------------------------------------------------------
Year               A year in the ISO-8601 calendar system, such as 2007.
-----------------------------------------------------------------------------------
YearMonth          A year-month in the ISO-8601 calendar system, such as 2007-12
-----------------------------------------------------------------------------------
ZonedDateTime      A date-time with a time-zone in the ISO-8601 calendar system,
                   such as 2007-12-03T10:15:30+01:00 Europe/Paris.
-----------------------------------------------------------------------------------
ZoneId             A time-zone ID, such as Europe/Paris.
-----------------------------------------------------------------------------------
ZoneOffset         A time-zone offset from Greenwich/UTC, such as +02:00.
-----------------------------------------------------------------------------------


Enum               Description
-----------------------------------------------------------------------------------
DayOfWeek          A day-of-week, such as 'Tuesday'.
-----------------------------------------------------------------------------------
Month              A month-of-year, such as 'July'.
-----------------------------------------------------------------------------------

Exception          Description
-----------------------------------------------------------------------------------
DateTimeException  Exception used to indicate a problem while calculating a date-time.

Java 9
- A number of parsing and formatting changes have been incorporated in Java 9 to
bring the functionality closer to Unicode Locale Data Markup Language (LDML).
These changes have been supervised by Stephen Colebourne, creator of the popular
 date-time library JodaTime, precursor of the new java.time component in Java 8.
Abiding by the Unicode standard will provide better interoperability with other
non-Java systems.

- LDML is the language used by the Unicode Common Locale Data Repository (CLDR),
  a project of the Unicode Consortium to gather and store locale data from
  different parts of the world, enabling application developers to better adapt
  their programs to different cultures. Among other things, LDML deals with dates,
  times, and timezones, and more particularly with date formatting and parsing.
  The following is an extract of new features coming in Java 9 that bring java.time
  closer to the LDML specification:

  - JDK-8148947, DateTimeFormatter pattern letter ‘g’: the letter ‘g’, as
    specified in LDML, indicates a “Modified Julian day”; this is different from a
    normal Julian day in the sense that a) it depends on local time, rather than GMT,
    and b) it demarcates days at midnight, as opposed to noon.
  - JDK-8155823, Add date-time patterns 'v' and 'vvvv’: ‘v’ and ‘vvvv’ are LDML
    formats to indicate “generic non-location format”, e.g. “Pacific Time”, as
    opposed to the “generic location format” with specifies a city, like
    “Los Angeles Time”.
  - JDK-8148949, DateTimeFormatter pattern letters ‘A’, ’n’, ’N’: although LDML
    doesn’t specify formats ’n’ and ’N’, it does specify ‘A’, but the current
    behaviour in Java doesn’t match that of the spec. ‘A’ is meant to represent the
    total number of milliseconds elapsed in the day, with variable width, but
    currently Java treats this as fixed with: if ‘AA’ is specified as a pattern, it
    will fail to parse any value that is further than 99 milliseconds in the day.
    ’n’ and ’N’ are just Java extensions to the standard to represent nanoseconds
    within the second, and nanoseconds within the day, respectively.
  - JDK-8079628, java.time DateTimeFormatter containing "DD" fails on three-digit
    day-of-year value: similar to the previous problem, but with ‘D’ representing
    days within a year. If one specifies “DD” as a pattern, it will fail to parse
    “123” as the 123th day of the year.
- As previously mentioned, a better alignment with the LDML will ease
  interoperability across systems, since there are multiple technologies that
  have adopted the LDML to some degree. Microsoft .NET uses LDML for general
  interexchange of locale data, and there are packages available for Node.js
  and Ruby, just to mention a few.
TimeUnit
@[https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/TimeUnit.html]
- JDK 1.5+
- Represents time durations at a given unit of granularity and
  provides utility methods to convert across units, and to perform
  timing and delay operations in these units.
Enums: DAYS HOURS MICROSECONDS MILLISECONDS MINUTES NANOSECONDS SECONDS

  void      sleep(long timeout)
  void  timedJoin(Thread thread, long timeout)
  void   timedWait(Object obj, long timeout)
  ...
ANNOTATIONS
ºpredefined annotation types in java.lang:º
- @Deprecated
- @Override
- @SuppressWarnings
- @SafeVarargs (SDK 1.? +) applied to a method/constructor,
                           asserts that the code does not perform
                           potentially unsafe operations
                           on its varargs parameter.
                           removing  related warnings

ºAnnotation types are a form of interfaceº
DECLARATION(interface is preceded by the @ sign) │ USAGE
  @Documented                                    │
  @interface ClassPreamble {                     │   @ClassPreamble (
     String   author        ()              ;    │      author         = "John Doe"      ,
     String   date          ()              ;    │      date           = "3/17/2002"     ,
     int      currentRev    () default 1    ;    │      currentRev     = 6               ,
     String   lastModified  () default "N/A";    │      lastModified   = "4/12/2004"     ,
     String   lastModifiedBy() default "N/A";    │      lastModifiedBy = "Jane Doe"      ,
     String[] reviewers     ()              ;    │      reviewers      = {"Alice", "Bob"}
  }                                              │   )
                                                 │ public class Generation3List extends Generation2List {
                                                 │     // ...
                                                 │ }
EXAMPLES
new @Interned MyObject();              ← Class instance creation expression

myString = (@NonNull String) str;      ← Type cast (1.8+)

class UnmodifiableList˂T˃ implements   ← implements clause
      @Readonly List˂@Readonly T˃
      { ... }

void monitorTemperature() throws       ← throws exception declaration
@Critical TemperatureException { ... }

@SuppressWarnings(value = "unchecked") ← Predefined standard annotations
void myMethod() { ... }
@SuppressWarnings({"unchecked", "deprecation"})
void myMethod() { ... }
META-ANNOTATTONS
(Annotations applying to other annotations)

º@Retentionº
RetentionPolicy.SOURCE: retained only in source (ignored by the compiler)
RetentionPolicy.CLASS : retained by compiler    (ignored by the JVM)
RetentionPolicy.RUNTIME:retained by JVM, can be queried at Runtime

º@Documentedº                     º@Repeatableº
- indicates that whenever the     - (1.8+)
  specified annotation is used    - targeted annotation can be applied
  those elements should be          more than once to the same
  documented using the Javadoc      declaration or type use.
  tool. (By default, annotations    Ex:
  are not included in Javadoc.)     @Author(name = "Jane Doe")
                                    @Author(name = "John Smith")
                                    class MyClass { ... }


º@Targetº                          º@Inheritedº
º(field,type,class..)º             - targeted annotation type can be inherited
- restrict targeted java-language    from the super class. (false by default.)
  elements where the annotation      When the user queries the annotation type
  can be applied:                    and the class has no annotation for this
  - ElementType.ANNOTATION_TYPE      type, the class'superclass is queried for
  - ElementType.CONSTRUCTOR          the annotation type.
  - ElementType.FIELD
  - ElementType.LOCAL_VARIABLE
  - ElementType.METHOD
  - ElementType.PACKAGE
  - ElementType.PARAMETER
  - ElementType.TYPE (1.8+)
SLF4j Logging
Simple Log Facade or abstraction for various logging frameworks
(e.g. java.util.logging, logback, log4j) allowing the end user
to plug in the desired logging framework at deployment time.

─────────┬──────────────────────────────────────────────────────────┬────────────────────────┬─────────────────────────────────────────────────────────
ºpom.xmlº│                                                          │Bºlogbackº configuration│
─────────┘                                                          ├────────────────────────┘
                                                                    │ (src/main/resources/)logback.xml
˂dependency˃*                                                       │ ˂?xml version="1.0" encoding="UTF-8"?˃
  ˂groupId˃org.slf4j˂/groupId˃                                      │ ˂configuration˃
  ˂artifactId˃slf4j-api˂/artifactId˃                                │     ˂!-- ˂jmxConfigurator /˃ --˃
  ˂version˃1.7.21˂/version˃                                         │     ˂appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"˃
˂/dependency˃                                                       │         ˂file˃log˂/file˃
...                                                                 │         ˂rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"˃
˂dependency˃                                                        │             ˂!-- daily rollover --˃
  ˂groupId˃ch.qos.logback˂/groupId˃                                 │             ˂fileNamePattern˃%d{yyyy-MM-dd}.log.zip˂/fileNamePattern˃
  ˂artifactId˃logback-classic˂/artifactId˃  ← add Bºlogbackº facade │             ˂maxFileSize˃1MB˂/maxFileSize˃
  ˂exclusions˃                                                      │             ˂!-- keep 2 days' worth of history capped at 1MB total size --˃
    ˂!-- Avoid problem:                                             │             ˂maxHistory˃2˂/maxHistory˃
         SLF4J: Class path contains multiple SLF4J bindings.        │             ˂totalSizeCap˃2MB˂/totalSizeCap˃
    ...   slf4j-jdk14-1.7.21.jar!...StaticLoggerBinder.class        │         ˂/rollingPolicy˃
    ...logback-classic-1.1.7.jar!...StaticLoggerBinder.class        │         ˂encoder˃
    --˃                                                             │             ˂pattern˃%date %level [%thread] %logger{10} [%file:%line] %msg%n˂/pattern˃
    ˂exclusion˃                                                     │         ˂/encoder˃
      ˂groupId˃org.slf4j˂/groupId˃                                  │     ˂/appender˃
      ˂artifactId˃slf4j-jdk14˂/artifactId˃                          │
    ˂/exclusion˃                                                    │     ˂appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"˃
  ˂/exclusions˃                                                     │         ˂encoder˃
  ˂version˃1.1.7˂/version˃                                          │             ˂pattern˃%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n˂/pattern˃
˂/dependency˃                                                       │         ˂/encoder˃
─────────────────────────────┬──────────────────────────────────────│     ˂/appender˃
ºExample Ussage in Java codeº│                                      │
─────────────────────────────┘                                      │     ˂logger name="my.company.package" level="INFO"/˃
import org.slf4j.Logger;                                            │     ˂logger name="my.company.package.subpackage" level="DEBUG"/˃
import org.slf4j.LoggerFactory;                                     │     ˂logger name="org.eclipse.jetty" level="INFO"/˃
...                                                                 │
  class MyClass {                                                   │     ˂root level="WARN"˃
    private static final Logger log =                               │         ˂appender-ref ref="STDOUT" /˃
       LoggerFactory.getLogger(AbstractRequestHandler.class);       │         ˂appender-ref ref="FILE" /˃
    ...                                                             │     ˂/root˃
    if (log.isDebugEnabled()) {                                     │ ˂/configuration˃
    //  ^ Avoid slow String construction                            │──────────────────────────────────────────────────────────────────────────────────
    //    if loGºNOTºenabled                                        │
        log.debug("Lorem ipsum... @{} {}", "param1", "param2");     │
    }                                                               │
    ...                                                             │
Functional
Lambdas
Sytnax:
(parameters) -˃ expression
(parameters) -˃  { statements; }

// takes a Long, returns a String
Function˂Long, String˃ f = (l) -˃ l.toString();

// takes nothing, gives you Thread
Supplier˂Thread˃ s = Thread::currentThread;

//  takes a string as the parameter
Consumer˂String˃ c = System.out::println;

// use lambdas in streams
new ArrayList˂String˃().stream()....

// peek: Debug streams without changes
peek ( e -˃ System.out.println(e)). ...

// map: Convert every element into something
map ( e -˃ e.hashCode())...

// filter (hc -˃ (hc % 2) == 0) ...

// collect all values from the stream
collect(Collectors.toCollection(TreeSet::new))
java.utility.function
@[https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
@[https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html]
- JDK 1.8+
- Incomplete but good enough to cover the "shape" of many lambda expressions and
 method references representing abstract concepts like functions, actions, or predicates
- The @FunctionalInterface is used to capture design intent (not needed by compiler).
- In documenting functional interfaces, or referring to variables typed as
  functional interfaces, it is common to refer directly to those abstract concepts,
  for example using "this function" instead of "the function represented by this object".
- Each functional interface has a single abstract method, called the functional method for that
  functional interface, to which the lambda expression's parameter and return types are matched or adapted.
- Functional interfaces can provide a target type in multiple contexts, such as assignment context, method invocation,
  or cast context:
  |Predicate˂String˃ p = String::isEmpty;           // Assignment context
  |stream.filter(e -˃ e.getSize() ˃ 10)...          // Method invocation context
  |stream.map((ToIntFunction) e -˃ e.getSize())...  // Cast context
Defined functions in 1.8
────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────
           Interface Summary                │           Interface Description
────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────
                  BiConsumer‹T,U›           │opt. accepting two input arguments and returns no result
  (|Double|Int|Long)Consumer‹T›             │opt. accepting a single (Object|double|int|long)input argument and returns no result
Obj(Double|Int|Long)Consumer‹T›             │opt. accepting an object-valued and a (double|int|long)-valued argument, and returns no result
────────────────────────────────────────────│────────────────────────────────────────────────────────────────────────────────
        (|Double|Long|Int)Function‹(T,)R›   │func. that accepts an (T|double,long,int) argument and produces a result
       (|Double|Long)ToIntFunction          │func. that accepts a (T|double|long)argument and produces an int-valued result
(ToDouble|ToLong|ToInt|)BiFunction‹(T,)U,R› │func. that accepts two arguments and produces an (T,double,long,int) result.
           To(Double|Long)Function‹T›       │func. that produces a (double|long)-valued result
(Int|Long|Double)To(Int|Long|Double)Function│func. that accepts a (int|long|double) argument and produces a (int|long|double) result
────────────────────────────────────────────│────────────────────────────────────────────────────────────────────────────────
 (|Int|Long|Double)UnaryOperator‹T›         │op. on a single (T|int|long|double) operand that produces a result of the same type
(Double|Long|Int|)BinaryOperator‹T›         │op. upon two (T|int|long|double) operands and producing a result of the same type
────────────────────────────────────────────│────────────────────────────────────────────────────────────────────────────────
                BiPredicate‹T,U›            │predicate (boolean-valued function) of two arguments
(|Int|Long|Double)Predicate‹T›              │predicate (boolean-valued function) of one (T|int|long|double) argument
────────────────────────────────────────────│────────────────────────────────────────────────────────────────────────────────
(|Boolean|Int|Long|Double)Supplier(‹T›)     │supplier of (T|Boolean|Int|long|double) results
────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────
Collections
   Comparative
Standard Rºnon-concurrentº SDK:
       ┌──────────────────────────────────────────────────────────────────────────────────────────
       │                                IMPLEMENTATIONS
       ├──────────────────────────────────────────────────────────────────────────────────────────
       │ Hash Table        │ Resizable Array   │Balanced Tree │ Linked List │ HashTable+LinkedList
       │                   │                   │              │             │
┌──────┼───────────────────┼───────────────────┼──────────────┼─────────────┼─────────────────────
│˂Set˃ │ HashSet           │                   │  TreeSet     │             │ LinkedHashSet
│      │                   │                   │              │             │
├──────┼───────────────────┼───────────────────┼──────────────┼─────────────┼─────────────────────
│˂List˃│                   │ ArrayList         │              │ LinkedList  │
│      │                   │ Vector            │              │ LinkedList  │
├──────┼───────────────────┼───────────────────┼──────────────┼─────────────┼─────────────────────
│˂Map˃ │ HashMap,Hashtable │                   │  TreeMap     │             │ LinkedHashMap
└──────┴───────────────────┴───────────────────┴──────────────┴─────────────┴─────────────────────
ºINTERFACESº
@[http://download.oracle.com/javase/6/docs/api/java/util/HashSet.html]
@[http://download.oracle.com/javase/6/docs/api/java/util/TreeSet.html]
@[http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html]
@[http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html]
@[http://download.oracle.com/javase/6/docs/api/java/util/LinkedList.html]
@[http://download.oracle.com/javase/6/docs/api/java/util/HashMap.html]
@[http://download.oracle.com/javase/6/docs/api/index.html]
@[http://download.oracle.com/javase/6/docs/api/java/util/TreeMap.html]
@[http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html]


ref
┌─────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│Collection       │ Thread-safe                ┃          YOUR DATA              ┃           OPERATIONS    ALLOWED       │
│                 │ alternative                ┃─────────────────────────────────┃───────────────────────────────────────┤
│class            │                            ┃Individu│Key-val.│Duplica│Primite┃ Iteration Order │Fast │ Random Access │
│                 │                            ┃elements│  pairs │element│support┃FIFO │Sorted│LIFO│'has'│By  │By   │By  │
│                 │                            ┃        │        │support│       ┃     │      │    │check│Key │Val  │Idx │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│HashMap          │ ConcurrentHashMap          ┃        │YES     │       │       ┃     │      │    │YES  │ YES│     │    │
│                 │                            ┃        │        │       │       ┃     │      │    │     │    │     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│SortedMap        │ ?                          ┃        │YES     │       │       ┃     │      │    │?    │ YES│     │    │
│                 │                            ┃        │        │       │       ┃     │      │    │     │    │     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│NavigableMap @1  │ ?                          ┃        │YES     │       │       ┃     │      │    │?    │ YES│     │    │
│                 │                            ┃        │        │       │       ┃     │      │    │     │    │     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│HashBiMap(Guava) │ Maps.syncrhonizedBiMap     ┃        │YES     │       │       ┃     │      │    │YES  │ YES│YES  │    │
│                 │ (new HashBiMap())          ┃        │        │       │       ┃     │      │    │     │    │     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│ArrayListMultimap│ Maps.synchronizedMultiMap  ┃        │YES     │YES    │       ┃     │      │    │YES  │ YES│     │    │
│   (Guava)       │ (new ArrayListMultimap())  ┃        │        │       │       ┃     │      │    │     │    │     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│LinkedHashMap    │ Collections.syncrhonizedMap┃        │YES     │       │       ┃YES  │      │    │YES  │ YES│     │    │
│                 │ (new LinkedHashMap())      ┃        │        │       │       ┃     │      │    │     │    │     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│TreeMap          │ ConcurrentSkipListMap      ┃        │YES     │       │       ┃     │YES   │    │YES  │ YES│     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│Int2IntMap       │                            ┃        │YES     │       │YES    ┃     │      │    │YES  │ YES│     │YES │
│(Fastutil)       │                            ┃        │        │       │       ┃     │      │    │     │    │     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│ArrayList        │ CopyOnWriteArrayList       ┃YES     │        │YES    │       ┃YES  │      │YES │     │    │     │YES │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│HashSet          │ Collections.newSetFromMap  ┃YES     │        │       │       ┃     │      │    │YES  │    │YES  │    │
│                 │ (new ConcurrentHashMap())  ┃        │        │       │       ┃     │      │    │     │    │     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│IntArrayList     │                            ┃YES     │        │YES    │YES    ┃YES  │      │YES │     │    │     │YES │
│(Fastutil)       │                            ┃        │        │       │       ┃     │      │    │     │    │     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│PriorityQueue    │ PriorityBlockingQueue      ┃YES     │        │YES    │       ┃     │YES   │    │     │    │     │    │
┼─────────────────┼────────────────────────────┃────────┼────────┼───────┼───────┃─────┼──────┼────┼─────┼────┼─────┼────┤
│ArrayDeque       │ ArrayBlockingQueue         ┃YES     │        │YES    │       ┃YES  │      │YES │     │    │     │    │
└─────────────────┴────────────────────────────┃────────┴────────┴───────┴───────┃─────┴──────┴────┴─────┴────┴─────┴────┘

 Collection class │  Random access by idx/key │ Search/Contains │ Instert
 ─────────────────┼───────────────────────────┼─────────────────┼───────────
 ArrayList        │  O(1)                     │ O(n)            │ O(n)
 HashSet          │  O(1)                     │ O(1)            │ O(1)
 HashMap          │  O(1)                     │ O(1)            │ O(1)
 TreeMap          │  O(log(n))                │ O(log(n))       │ O(log(n))

@1 NavigableMap: SortedMap with additional methods for finding entries
                 by their ordered position in the key set.
                 So potentially this can remove the need for iterating
                 in the first place - you might be able to find the
                 specific entry you are after using the higherEntry,
                 lowerEntry, ceilingEntry, or floorEntry methods. The
                 descendingMap method even gives you an explicit method
                 of reversing the traversal order.




Initialization
ºINITIALIZING A LISTº
final List˂String˃ myList =                  ← final forbid re-asigning the list,
      Arrays.asList("one", "two", "three");     but its content is still mutable
      myList.add("four");

final List˂String˃ myInmmutableList =        ← inmutable version (thread safe)
      Collections.unmodifiableList(myList);

ºINITIALIZING A MAPº
final Map˂String,String˃ myMap =             ← Mutable map (even if 'final' used)
      new HashMap˂String,String˃();
        myMap.put("k1", "k2");
        myMap.put("v1", "v2");
final Map˂String,String˃ myInmutableMap =    ← Inmutable version of map
      Collections.unmodifiableMap(temp);

final HashMap˂String,String˃ data =          ← Java 7+
      HashMapBuilder.build(
          "k1","v1",                         ← must have an even number of elements
          "k2","v2");

final Map˂String, String˃ test =             ← Java 9+
      Map.of("k1", "k2", "v1", "v2");        ← must have an even number of elements

final Map˂String, String˃ test2 =            ← Java 9+
      Map.ofEntries( entry("k1", "k2"),...);

final Map˂String, String˃ test =             ← Guava ImmutableMap
      ImmutableMap.of("k1","v1", ...);         works only with up to 5 key/value pairs

final Map˂String, String˃ test =             ← Guava ImmutableMap alternative
      ImmutableMap.˂String, String˃builder()
      .put("k1", "v1")
      .put("k2", "v2")
      ...
      .build();
Walk-over/iterate
ºfor collection walkº
 │for (
 │     int idx = 0;
 │     idx ˂ºcollectionºOº.lengthº;
 │     idx++) {
 │  //r*WARN:
 │  //  - Very slow for LinkedLists*
 │  //  - Faster for other List implementations
 │  type array_element =ºcollectionºOº.get(idx);º
 │}

 │for (                                                │ for (
 │     Iterator iterator =ºcollectionºOº.iterator()º;  │      iterable_type iterable_element Oº:collectionº
 │     Oºiterator.hasNext();º) {                       │     ) {
 │  //ºBest option when removing/modifying elementsº/  │   //ºBest option when NOT remov./modify. elementsº
 │  type type = (type) Oºiterator.next()º;             │   ...
 │}                                                    │ }


ºSTREAMS (Java 8+)º
ºcollectionºOº.forEachº((Oºitº) -˃ {
    System.out::println(Oºitº)
});
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 Shorter alternative:
ºcollectionºOº.forEachº(System.out::println);

ºWALK-OVER/ITERATE A MAPº

ºentrySet Java 5+º                         | ºUSING ITERATORSº                           | ºUSING FOR-EACHº
 Map˂String, String˃ map = ...             |  Iterator˂Map.Entry˂Integer, Integer˃˃ºitº= |  long i = 0;
 for (                                     |      map.entrySet()Oº.iterator()º;          |  for (
      Map.Entry˂String, String˃ Oºentryº : |  while (ºitºOº.hasNext()º) {                |       Map.Entry˂Integer, Integer˃ pair :
     ºmapºOº.entrySet()º)                  |      Map.Entry˂Integer, Integer˃ pair =     |         ºmyMapºOº.entrySet()º) {
 {                                         |       ºitºOº.next()º;                       |    log.debug( "{}:{}"      ,
   log.debug( "{}:{}"          ,           |    log.debug( "{}:{}"      ,                |             pair.getKey()  ,
            Oºentryº.getKey()  ,           |             pair.getKey()  ,                |             pair.getValue() );
            Oºentryº.getValue());          |             pair.getValue() );              |  }
 }                                         |  }

ºforEach (java 8+)º                        |ºiterating over keySetº          | ºfor + Map.Entryº
 final long[] i = {0};                     | long i = 0;                     |  for (
 ºmapºOº.forEachº((k, v) -˂ i[0] += k + v);| Iterator˂Integer˃ itr2 =        |     Iterator˂Map.Entry˂Integer, Integer˃˃
                                           |    mapOº.keySet().iterator()º;  |        entries = map.entrySet().iterator() ;
                                           | while (itr2.hasNext()) {        |     entries.hasNext();
                                           |     Integer key = itr2.next();  |     ) {
                                           |     i += key + map.get(key);    |   Map.Entry˂Integer, Integer˃
                                           | }                               |      entry = entries.next();
                                                                             |   log.debug( "{}:{}"      ,
                                                                             |           entry.getKey()  ,
                                                                             |           entry.getValue() );
                                                                             |  }
|ºStream API (1.8+)º              |ºStream API parallel (1.8+)º
| final long[] i = {0};           | final long[] i = {0};
| ºmapºOº.entrySet().stream()º    | ºmapºOº.entrySet().stream()º.
|  .forEach(                      |   parallel()*.forEach(e -˃
|    ...e.getKey(), e.getValue()  |    ... e.getKey() , e.getValue()
| );                              | )
java.util.Collections
Utility class
@[https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html]
- Utility class with static methods that operate on or return collections

Collections.EMPTY_LIST // The empty (immutable) list
Collections.EMPTY_MAP  // The empty (immutable) map
Collections.EMPTY_SET  // The empty (immutable) set

Enumeration  Collections.emptyEnumeration()  // Returns an enumeration that has no elements.
Iterator     Collections.emptyIterator()     // Returns an iterator that has no elements.
List         Collections.emptyList()         // Returns the empty list (immutable)                                              .
ListIterator Collections.emptyListIterator() // Returns a list iterator that has no elements.
Map          Collections.emptyMap()          // Returns the empty map (immutable)                                              .
Set          Collections.emptySet()          // Returns the empty set (immutable)                                              .



boolean      Collections.addAll(Collection c, T... elements)           Adds all elements to collection 'c'
Queue        Collections.asLifoQueue(Deque deque)                      deque → LIFO Queue view
int          Collections.binarySearch(List list, T key)                Searches key into List using binary search.
int          Collections.binarySearch(List list, T key, Comparator c)  Searches key into List using binary search an comparator.

Collection   Collections.checkedCollection(Collection c, Class type)   Returns a dynamically typesafe view of input collection/list/...
List         Collections.checkedList(List list, Class type)
Map          Collections.checkedMap
                         (Map m, Class keyType, Class valueType)
Set          Collections.checkedSet(Set s, Class type)
SortedMap    Collections.checkedSortedMap
                         (SortedMap m, Class keyType, Class valueType)


SortedSet    Collections.checkedSortedSet(SortedSet s, Class type)
void         Collections.copy(List dest, List src)                     Copies src list elements to dest list
boolean      Collections.disjoint(Collection c1, Collection c2)        true if c1/c2 have no elements in common.

Enumeration  Collections.enumeration(Collection c)                     Returns an enumeration over the specified collection.

void         Collections.fill(List list, T obj)                        Replaces all of the elements of the specified list with the specified element.
int          Collections.frequency(Collection c, Object o)             Returns the number of elements in the specified collection equal to the specified object.
int          Collections.indexOfSubList(List source, List target)      Returns the starting position of the first occurrence of the specified target list within the specified source list, or -1 if there is no such occurrence.
int          Collections.lastIndexOfSubList(List source, List target)  Returns the starting position of the last occurrence of the specified target list within the specified source list, or -1 if there is no such occurrence.
ArrayList    Collections.list(Enumeration e)                           Returns an array list containing the elements returned by the specified enumeration in the order they are returned by the enumeration.
T            Collections.max(Collection coll)                          Returns the maximum element of the given collection, according to the natural ordering of its elements.
T            Collections.max(Collection coll, Comparator comp)         Returns the maximum element of the given collection, according to the order induced by the specified comparator.
T            Collections.min(Collection coll)                          Returns the minimum element of the given collection, according to the natural ordering of its elements.
T            Collections.min(Collection coll, Comparator comp)         Returns the minimum element of the given collection, according to the order induced by the specified comparator.
List         Collections.nCopies(int n, T o)                           Returns an immutable list consisting of n copies of the specified object.
Set          Collections.newSetFromMap(Map map)                        Returns a set backed by the specified map.
boolean      Collections.replaceAll(List list, T oldVal, T newVal)     Replaces all occurrences of one specified value in a list with another.
void         Collections.reverse(List list)                            Reverses the order of the elements in the specified list.
Comparator   Collections.reverseOrder()                                Returns a comparator that imposes the reverse of the natural ordering on a collection of objects that implement the Comparable interface.
Comparator   Collections.reverseOrder(Comparator cmp)                  Returns a comparator that imposes the reverse ordering of the specified comparator.
void         Collections.rotate(List list, int distance)               Rotates the elements in the specified list by the specified distance.
void         Collections.shuffle(List list)                            Randomly permutes the specified list using a default source of randomness.
void         Collections.shuffle(List list, Random rnd)                Randomly permute the specified list using the specified source of randomness.
Set          Collections.singleton(T o)                                Returns an immutable set containing only the specified object.
List         Collections.singletonList(T o)                            Returns an immutable list containing only the specified object.
Map          Collections.singletonMap(K key, V value)                  Returns an immutable map, mapping only the specified key to the specified value.
void         Collections.sort(List list)                               Sorts the specified list into ascending order, according to the natural ordering of its elements.
void         Collections.sort(List list, Comparator c)                 Sorts the specified list according to the order induced by the specified comparator.
void         Collections.swap(List list, int i, int j)                 Swaps the elements at the specified positions in the specified list.
Collection   Collections.synchronizedCollection(Collection c)          Returns a synchronized (thread-safe) collection backed by the specified collection.
List         Collections.synchronizedList(List list)                   Returns a synchronized (thread-safe) list backed by the specified list.
Map          Collections.synchronizedMap(Map m)                        Returns a synchronized (thread-safe) map backed by the specified map.
Set          Collections.synchronizedSet(Set s)                        Returns a synchronized (thread-safe) set backed by the specified set.
SortedMap    Collections.synchronizedSortedMap(SortedMap m)            Returns a synchronized (thread-safe) sorted map backed by the specified sorted map.
SortedSet    Collections.synchronizedSortedSet(SortedSet s)            Returns a synchronized (thread-safe) sorted set backed by the specified sorted set.
Collection   Collections.unmodifiableCollection(Collection c)          Returns an unmodifiable view of the specified collection.
List         Collections.unmodifiableList(List list)                   Returns an unmodifiable view of the specified list.
Map          Collections.unmodifiableMap(Map m)                        Returns an unmodifiable view of the specified map.
Set          Collections.unmodifiableSet(Set s)                        Returns an unmodifiable view of the specified set.
SortedMap    Collections.unmodifiableSortedMap(SortedMap m)            Returns an unmodifiable view of the specified sorted map.
SortedSet    Collections.unmodifiableSortedSet(SortedSet s)            Returns an unmodifiable view of the specified sorted set.
Fastutil
- Fast and compact type-specific collections for Java
  Great default choice for collections of primitive types,
  like int or long. Also handles big collections with more than 2
  31 elements well.
Eclipse Collections
(Originated from Goldman Sachs gs-collection:
 @[https://github.com/goldmansachs/gs-collections])
- Features you want with the collections you need
  Previously known as gs-collections, this library
  includes almost any collection you might
  need: primitive type collections, multimaps,
  bidirectional maps and so on.
Guava Collections
- Google Core Libraries for Java 6+
  Perhaps the default collection library for Java
  projects. Contains a magnitude of convenient
  methods for creating collection, like fluent
  builders, as well as advanced collection types
˂˂Enumeration˃˃(1.0)
vs
˂˂Iterator˃˃(1.7)
@[https://stackoverflow.com/questions/948194/difference-between-java-enumeration-and-iterator]

- both interfaces will give successive elements

- Iterators allow the caller to remove elements from
  the underlying collection during the iteration with
  well-defined semantics.
  (additional remove method)
- Iterators Method names have been improved.

- Iterators are fail-fast:
  - If thread A changes the collection, while
       thread B is traversing it, the iterator implementation
       will try to throw a ConcurrentModificationException
       (best effort since it can not always be guaranteed)
  - The fail-fast behavior of iterators can be used only to
    detect bugs sin the best effort doesn't warrant its trigger.
  - newer 'concurrent' collections will never throw it.
    Reading thread B will traverse the collection "snapshot" at
    the start of read.



-ºIterator should be preferred over Enumerationº
  taking the place of Enumeration in collections framework


  Enumeration     │ Iterator
  ────────────────┼────────────
  hasMoreElement()│ hasNext()
  nextElement()   │ next()
                  │ remove() ← optional: not implemented in many classes
NIO
NIO (1.4+)
- Replaced OLD blocking IO based on [ byte/char, read-or-write streams ]
┌──────────┐     ┌──────────────┐                                  ┌───────────────┐
│ºCORE NIOº│     │ºNON─BLOCKINGº│                                  │ ºNON─CORE NIOº│
├──────────┴───┐ ├──────────────┴────────────────────────────────┐ ├───────────────┴───────────────────────────────────────────
│ ─BºCHANNELS º│ │· a thread requests a channel the intention    │ │ ─ components like Pipe and FileLock can be considered
│  ─ read/write│ │  to read/write data into a buffer:            │ │   "utility classes" supporting the first three ones.
│ ─BºBUFFERS  º│ │  · While the channel moves data into/from     │ │
│ ─BºSELECTORSº│ │   the buffer, the thread continues another job│ │ ─ "SELECTORS" objects monitor one+ channels for events
└──────────────┘ │  · When data is ready, the thread is notified │ │   (connection opened, data arrived, ..):
                 └───────────────────────────────────────────────┘ │   ─ Thus, a single thread can monitor multiple channels for data.
Channel  : File,Datagram/UDP,Socket/TCP,ServerSocket,...           │     (Very handy if app has many connections/Channels/clients open
Buffer of: Byte|Char|Double|Float|Int|Long|Short|MappedByte)Buffer │     but with low traffic on each connection.
                                                                   │   ─ To use selectors:
                                                                   │     ─ Instantiate the selector
                                                                   │     ─ Register one+ channels with it
                                                                   └───────────────────────────────────────────────────────────────
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ºBUFFERº                                                                                          │
│ ºATTRIBUTESº                                            ºMETHODSº                                │
│          ┌─────────────────┬───────────────────────────┐ ┌─────────────┬───────────────────────┐ │
│          │ºwriteºmode      │ ºreadºmode                │ │rewind()     │                       │ │
│ ┌────────┼─────────────────┴───────────────────────────┤ │             │                       │ │
│ │capacity│ fixed size of memory block implementing     │ ├─────────────┼───────────────────────│ │
│ │        │ the buffer                                  │ │clear()      │                       │ │
│ ├────────┼─────────────────┬───────────────────────────┤ │compact()    │                       │ │
│ │position│ starts at 0,    │ starts at 0 (after "flip")│ ├─────────────┼───────────────────────│ │
│ │        │ increase at each│ increase at each          │ │mark()       │"bookmark position"    │ │
│ ├────────┼─────────────────┼───────────────────────────┤ │reset()      │ and return "bookmark" │ │
│ │   limit│ element written │ element read              │ ├─────────────┼───────────────────────│ │
│ │        │ == capacity     │ == last written position  │ │equals()     │using only the         │ │
│ └────────┴─────────────────┴───────────────────────────┘ │compareTo()  │remaining-to-read bytes│ │
│                                                          │             │for the computation    │ │
│                                                          └─────────────┴───────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────
│ºSEQUENCE TO READ/WRITE DATAº                  ┌───────┐
│try (  /* try-with 1.7+ */                     │SUMMARY│
│  RandomAccessFile GºaFileº =                  ├───────┴──────────────────────────
│    new RandomAccessFile("nio-data.txt", "rw") │-1 ) Write data into the Buffer
│) throws IOException {                         │-2 ) Call buffer.ºflip()º
│  FileChannel BºinChannelº =                   │     switch writing/reading mode
│    GºaFileº.getChannel();                     │-3 ) Read data out of the Buffer
│                                               │-4a) buffer.clear();  ← alt1: clear all buffer
│  ByteBuffer Oºbufº=                           │-4b) buffer.compact() ← alt2: clear only data read
│      ByteBuffer.allocate(48 /*capacity*/);    ├────────────────────────────────────
│                                               │ channelIn → (data) → buffer
│                                               │ buffer    → (data) → channelOut
│  int ºbytesReadº=                             └────────────────────────────────────
│       BºinChannelº.read(Oºbufº);  // ← Oºbufº now
│                                          in write mode
│Rºwhileº (ºbytesReadº != -1)
│Rº{º
│    Oºbufº.ºflipº();               // ← Oºbufº now
│    while(Oºbufº.hasRemaining()){         in read mode
│        System.out.print(
│           (char) Oºbufº.get()     // ← alt.1: read 1 byte
│        );                                     at a time
│        // channel2.write(Oºbufº)  // ← alt.2: read data
│    }                                         in channel2
│    Oºbufº.clear();                // ← make buffer
│                                        ready-for-writing
│    ºbytesReadº = BºinChannelº     // ← Oºbufº now
│                    .read(Oºbufº);        in write mode
│Rº}º
│}
ºSCATTER-GATHERº
┌──────────────────────────────────────────────────┬──────────────────────────────────────────────────┐
│ ºscattering channel readº                        │ºscattering-write to channelº                     │
│ - channel → read to → buffer1, buffer2, ....     │ - buffer1, buffer2, ...→ write to → channel      │
│ - Ex:                                            │ - ex:                                            │
│   ByteBuffer header = ByteBuffer.allocate(128);  │   ByteBuffer header = ByteBuffer.allocate(128);  │
│   ByteBuffer body   = ByteBuffer.allocate(1024); │   ByteBuffer body   = ByteBuffer.allocate(1024); │
│   ByteBuffer[] OºbufferArrayº = { header, body };│   ByteBuffer[] OºbufferArrayº = { header, body };│
│ Bºchannelº.read(OºbufferArrayº);                 │ Bºchannelº.write(OºbufferArrayº);                │
│            ^^^^                                  │                                                  │
│ fill up one buffer before moving on to the next  │                                                  │
│ (*not suited for undefined size messages)        │                                                  │
└──────────────────────────────────────────────────┴──────────────────────────────────────────────────┘

ºCHANNEL-TO-CHANNELº
-ºIf one the the channels is FileChannelº:
  - FileChannelºtransferTo()/transferFrom()º can be used to move data between channels
  RºWARN:ºSome SocketChannel implementations may transfer only the data the SocketChannel
    has ready in its internal buffer here and now
  ┌─────────┐
  │Examples.│
  ├─────────┴───────────────────────────────────┬─────────────────────────────────────────────┐
  │  FileChannelGºfromChannelº=                 │  FileChannelGºfromChannelº=                 │
  │     (new RandomAccessFile("from.txt", "rw"))│     (new RandomAccessFile("from.txt", "rw"))│
  │     .getChannel(),                          │     .getChannel(),                          │
  │  FileChannel BºtoChannelº=                  │  FileChannel BºtoChannelº=                  │
  │     (new RandomAccessFile(  "to.txt", "rw"))│     (new RandomAccessFile(  "to.txt", "rw"))│
  │     .getChannel();                          │     .getChannel();                          │
  │  long count    =GºfromChannelº.size();      │  long count    = ;                          │
  │BºtoChannelºº.transferFromº(                 │GºfromChannelºº.transferToº(                 │
  │     GºfromChannelº,                         │      0 /*position*/,                        │
  │       0       , // posit.in dest-file to    │    GºfromChannelº.size() /*count*/,         │
  │                 // start writing from       │    BºtoChannelº);                           │
  │       maxCount  /* max-bytes to transfer*/  │                                             │
  │  );                ^^^^^^^^^                │                                             │
  │                    constrained by data      │                                             │
  │                    in source                │                                             │
  └─────────────────────────────────────────────┴─────────────────────────────────────────────┘
API tree
JDK 8
./java/nio/
           Bits ByteOrder CharBufferSpliterator
           ByteBufferAs(Char|Double|Float|...)Buffer(B|L|...
           (|Float|Double|StringChar)Buffer
           HeapByteBuffer Heap(Byte|Char|...)Buffer(R) HeapCharBuffer
           (Int|Long|...)Buffer
           (Mapped|Direct)ByteBuffer(R)
           Direct(Byte|Char|Double|...)Buffer

./java/nio/channels/
                    Channel Channels CompletionHandler FileLock MembershipKey Pipe Selector SelectionKey
                    Asynchronous(|Byte)Channel
                    AsynchronousChannelGroup
                    AsynchronousFileChannel
                    AsynchronousServerSocketChannel
                    AsynchronousSocketChannel
                    (Byte|Datagram|File|GatheringByte|Interruptible|Multicast|
                     Network|ReadableByte|ScatteringByte|SeekableByte|Selectable|
                     ServerSocket|Socket|WritableByte)Channel
                   /spi/Abstract(Interruptible|Selectable)Channel
                        Abstract(SelectionKey|Selector)
                        (AsynchronousChannel|Selector)Provider

./java/nio/charset/
                   Charset(|Decoder|Encoder) StandardCharsets
                   CoderResult CodingErrorAction
                  /spi/CharsetProvider

./java/nio/file/attribute/AclEntry(|Flag|Permission|Type)
                          (|AclFile|BasicFile|DosFile|File|
                            FileOwner|FileStore|PosixFile|
                            UserDefinedFile)AttributeView
                          (BasicFile|DosFile|PosixFile)Attributes
                          FileAttribute FileTime
                          GroupPrincipal

                          UserPrincipal(LookupService)
./java/nio/file/
                AccessMode CopyMoveHelper CopyOption DirectoryStream Files
                LinkOption LinkPermission Path        PathMatcher        Paths
                SecureDirectoryStream
                File(Store|System|Systems|TreeIterator|TreeWalker|VisitOption|Visitor|VisitResult)
                SimpleFileVisitor
                OpenOption    Standard(Copy|Open)Option
                StandardWatchEventKinds
                StandardWatchEventKinds$StdWatchEventKind
                TempFileHelper
                Watchable      Watch(Event|Key|Service)
                spi/FileSystemProvider
                    FileTypeDetector
SELECTORS
@[https://docs.oracle.com/javase/7/docs/api/java/nio/channels/Selector.html]

- A Selector allows a single thread to manage multiple channels
 (network connections), by examining which ones are
  ready for connect,accept,read,write

- A channel that "fires an event" is also said to be "ready" for that event.

ºREGISTERING A SELECTORº                              │ºUSING SELECTORSº
ºAND ASSIGNING CHANNELSº                              │
    │  Selector BºselectoRº = Selector.open();        │ ºSTEP 1º
    │  channel.configureBlocking(false);              │  call one of the select() methods
    │          ^^^^^^^^^^^^^^^^^^^^^^^^               │  (upon registering 1+ channels)
    │   //     non-blocking-mode required             │  int select(long mSecTimeout) ← block until channel/s ready
    │   // RºWARN:º FileChannel can NOT be switched   │             └────(optional)┘
    │   //   into NON-blocking mode and so            │  int selectNow()              ← Don't block even if none read
    │   //   they can NOT be used with selectors.     │  └┬┘
┌───→GºSelectionKey keyº = channel.register(          │  indicates how many channels became ready since last select() call.
│   │    Bºselectorº,                                 │
│   │    SelectionKey.OP_READ |                       │ ºSTEP 2º
│   │    SelectionKey.OP_WRITE);                      │  examine ready channels returned by select like:
│   │                 ^^^^^^^                         │  Set˂SelectionKey˃ selectedKeys =
│   │                 Or-set of interest:             │                    BºselectoRº.OºselectedKeys()º;
│   │                 OP_CONNECT / OP_ACCEPT          │  Iterator˂SelectionKey˃ keyIterator =
│   │                 OP_READ    / OP_WRITE           │                    selectedKeys.iterator();
│   │  ^^^^^^^^^^^^^^^^                               │  while(keyIterator.hasNext()) {
│   │                                                 │    GºSelectionKey keyº= keyIterator.next();
│ ┌─→Gºkeyº.attach(extraInfoObject);                  │      //  "cast to proper channel"
│ │ │  Object attachedObj =                           │             if (Gºkeyº.isAcceptable ()) {
│ │ │     selectionKey.attachment();                  │        ... connection accepted by ServerSocketChannel
│ │ │                                                 │      } else if (Gºkeyº.isConnectable()) {
│ │ │                                                 │        ... connection established with remote server
│ │ │ // After selection                              │      } else if (Gºkeyº.isReadable   ()) {
│ │ │ // ^^^^^^^^^^^^^^^                              │        ... channel ready for reading
│ │ │ // explained later                              │      } else if (Gºkeyº.isWritable   ()) {
│ │ │                                                 │        ... channel ready for writing
│ │ │ // Alternative 1:                               │      }
│ │ │ int OºreadySetº= Gºkeyº.readyOps();             │      keyIterator.remove();
│ │ │ boolean isAcceptable  =                         │  }
│ │ │         OºreadySetº ⅋ SelectionKey.OP_ACCEPT;   │ ºSTEP 3º
│ │ │ ...                                             │Bºselectorº.close()
│ │ │ // Alternative 2:                               │            ^^^^^
│ │ │ Gºkeyº.isAcceptable();                          │   must be called after finishing ussage,
│ │                                                   │   invalidating all SelectionKey instances
│ └─── (optional) user attached object,               │   registered with this Selector.
│      handy way to recognize a given                 │   The channels themselves are not closed.
│      channel, provide extra info
│      (buffer/s,...)
│
└─── Gºkeyº can be queried like:
       intOºinterestSetº = Gºkeyº.interestOps()*;
       boolean isInterestedInAccept
           = OºinterestSetº ⅋ SelectionKey.OP_ACCEPT;



NOTE:
-  A thread blocked by a call to select() can be forced to leave the select() method,
   even if no channels are yet ready by having a different thread call
   the BºselectoRº.ºwakeup()º method on the Selector which the first thread has
   called select() on:
   - The thread waiting inside select() will then return immediately.
   - If a different thread calls wakeup() and no thread is currently
     blocked inside select(), the next thread that calls select()
     will "wake up" immediately.
FileChannel
- Java NIO FileChannel: channel connected to a file allowing to
      read data from  and write data to a file.
- A FileChannel canNOT be set into non-blocking mode:
  It always runs in blocking mode

- Reading from FileChannel (Writting to buffer):
  |/* You cannot open a FileChannel directly,
  | * first you obtain a FileChannel via an (Input|Output)Stream or a RandomAccessFile
  | */
  |RandomAccessFile GºaFileº     = new RandomAccessFile("data/nio-data.txt", "rw");
  |// Reading from channel
  |try (  /* try-with 1.7+ */
  |  RandomAccessFile GºaFileº = new RandomAccessFile("data/nio-data.txt", "rw")
  |) throws IOException {
  |  FileChannel BºinChannelº = GºaFileº.getChannel();
  |
  |  ByteBuffer Oºbufº = ByteBuffer.allocate(48 /* capacity*/);
  |
  |  int ºbytesReadº = BºinChannelº.read(Oºbufº); // Oºbufº now in write mode
  |  while (ºbytesReadº != -1) {
  |    Oºbufº.flip();                            // Oºbufº now in read mode
  |    while(Oºbufº.hasRemaining()){
  |        // alt. read data directly, 1 byte at a time
  |        System.out.print((char) Oºbufº.get());
  |        // alt. read data in channel
  |        // anotherChannel.write(Oºbufº)
  |    }
  |
  |    Oºbufº.clear(); //make buffer ready for writing
  |    ºbytesReadº = BºinChannelº.read(Oºbufº); // Oºbufº now in write mode
  |  }

- Writing to a FileChannel (reading from buffer)
  | String newData = "......" + System.currentTimeMillis();
  | ByteBuffer Oºbufº = ByteBuffer.allocate(48);
  | Oºbufº.clear();
  | Oºbufº.put(newData.getBytes());
  | Oºbufº.flip(); // change buffer from write to read
  | ºwhile(Oºbufº.hasRemaining()) {º channelOº.writeº(Oºbufº); º}º
  | channel.close();


- FileChannel Position
  | long pos = fileChannel.position(); // obtain current position
  | fileChannel.position(pos +123); // change position

   - If you set the position after the end of the file,
     and try to read from the channel, you will get -1
   - If you set the position after the end of the file,
     and write to the channel, the file will be expanded
     to fit the position and written data. This may result
     in a "file hole", where the physical file on
     the disk has gaps in the written data.

- FileChannel Size
  | long fileSize = fileChannel.size();
                                ^^^^^^
                            size of the file
                            connected to channel

- FileChannel (file) Truncate
  | fileChannel.truncate(1024 /*length*/);

- FileChannel Force:
  flushes all unwritten data from the channel and OS cache to the disk
  | channel.force(true /* flush also file meta-data like permissions....*/);
Pipe
- one-way data connection between two threads
- Pipe =   source channel   ← One threads writes to sink
        +    sink channel   ← One threads reads from source

Ex:
  ByteBuffer Oºbufº = ByteBuffer.allocate(48);
  Oºbufº.clear();
  Oºbufº.put(newData.getBytes());

  // WRITING TO PIPE
  Pipe pipe = Pipe.open();
  Pipe.SinkChannel sinkChannel = pipe.sink();
  String newData = "..." + System.currentTimeMillis();
  Oºbufº.flip();
  while(Oºbufº.hasRemaining()) { sinkChannel.write(Oºbufº); }

  // READING FROM A PIPE
  To read from a Pipe you need to access the source channel. Here is how that is done:
  Pipe.SourceChannel sourceChannel = pipe.source();
  int ºbytesReadº = BºinChannelº.read(buf2);
SocketChannel
There are two ways a SocketChannel can be created:

// Opening a SocketChannel
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));

// Reading (writing to buffer)
ByteBuffer Oºbufº = ByteBuffer.allocate(48);
int ºbytesReadº = socketChannel.read(Oºbufº); // If -1 is returned, the end-of-stream is reached (connection is closed)

// Writing to a SocketChannel
String newData = "..." + System.currentTimeMillis();
ByteBuffer Oºbufº = ByteBuffer.allocate(48);
Oºbufº.clear();
Oºbufº.put(newData.getBytes());
Oºbufº.flip();
while(Oºbufº.hasRemaining()) { channel.write(Oºbufº); }

socketChannel.close();
Non-blocking Mode
- socketChannelº.configureBlocking(false)º;
- Calls to connect(), read() and write() will not block
- In non-blocking mode connect() calls may return before
  the connection is established:
  - To determine whether the connection is established
    use finishConnect() like this:

  | socketChannel.configureBlocking(false);
  | socketChannel.connect(
  |   new InetSocketAddress("http://jenkov.com", 80));
  |
  | while(! socketChannel.finishConnect() ){
  |     //wait, or do something else...
  | }

NOTE: non-blocking works much better with Selector's
ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.socket().bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false);

while(true){
    SocketChannel socketChannel =
            serverSocketChannel.accept(); // in blocking mode waits until incoming connection arrives
    if(socketChannel != null /* always false in blocking mode */){
        //do something with socketChannel...
    }

    //do something with socketChannel...
}

serverSocketChannel.close()
Datagram Channel
- Since UDP is a connection-less network protocol, you cannot just
  by default read and write to a DatagramChannel like you do from
  other channels. Instead you send and receive packets of data

  | DatagramChannel channel = DatagramChannel.open();
  | channel.socket().bind(new InetSocketAddress(9999));
  |
  | ByteBuffer Oºbufº = ByteBuffer.allocate(48);
  | Oºbufº.clear();
  | // WARN: if read data is bigger than buffer size remaining data is discarded silently
  | channel.receive(Oºbufº);
  |
  | // Write to channel
  | String newData = "..." + System.currentTimeMillis();
  | Oºbufº.clear();
  | Oºbufº.put(newData.getBytes());
  | Oºbufº.flip();
  |
  |
  | // WARN:  No notice is received about packet delivery (UDP does not make any guarantees)
  | int bytesSent = channel.send(Oºbufº, new InetSocketAddress("jenkov.com", 80));
  |
  | // Alternatively you can "Connect" to a Specific Address. Since UDP is connection-less,
  | // connecting to a remote address just means that the DatagramChannel can only send/receive
  | // data packets from a given specific address.
  | channel.connect(new InetSocketAddress("jenkov.com", 80));
  | int ºbytesReadº = channel.read(Oºbufº);
  | int bytesSent = channel.write(Oºbufº);
NonBlocking Server
REF:
- @[http://tutorials.jenkov.com/java-nio/non-blocking-server.html]
- @[https://github.com/jjenkov/java-nio-server]
- Non-blocking IO Pipelines:
read-write pipeline: ºchannelInº → selector → component → ... → componentN → ºchannelOutº
read-only  pipeline: ºchannelInº → selector → component → ... → componentN
write-only pipeline:                        component → ... → componentN → ºchannelOutº
Note: It is the component that initiates reading of data from the Channel via the Selector
read-pipeline read from stream/channelIn and split data into messages like:

Data   → Message → Message
Stream   Reader    Stream

-ºA blocking Message Reader/Writer is simpler, since itº
 ºhas never to handle situations where no data was readº
 ºfrom the stream, or where only a partial message wasº
 ºread from the stream and message parsing needs to beº
 ºresumed later.º
-ºThe drawback of blocking is the requirement of separateº
 ºthreads for each parallel stream, which is a problem if theº
 ºserver has thousands of concurrent connectionsº
- Each thread will take between 320K (32 bit JVM) and
  1024K (64 bit JVM) memory for its stack
- Queue messages can be used to reduce the problem. However,
  this design requires that the inbound client  streams
  send data reasonably often and input is processed fast.
   If the inbound client stream may be inactive for longer periods
  attached to hidden clients, a high number of inactive
  connections may actually block all the threads in the thread
  pool.
  That means that the server becomes slow to respond or even
  unresponsive.
- A non-blocking IO pipeline can use a single thread to
  read messages from multiple non-blocking streams.
    When in non-blocking mode, a stream may return 0 or more
  bytes when you attempt to read data from it.
  When you call select() or selectNow() on the Selector it
  gives you only the SelectableChannel instances ("connected
  clients") that actually has data to read.

OºComponent ──→ STEP 1: select() ──→ Selector ←──┬─→ Channel1º
Oº    ↑                                │         ┼─→ Channel2º
Oº    └───← STEP 2: ready channels ←───┘         └─→ Channel3º


- Reading Partial Messages: Data sent by "ready" channels can
  contain fractions/incomplete messages:
  - The Message Reader looks needs to check if the data block
    contains at least one full message, adn storing partial ones.
    (maybe using one Message Reader per Channel to avoid mixing messages)
  - To store Partial Messages two design should be considered:
    - copy data as little as possible for better performance
    - We want full messages to be stored in consecutive byte to
      make parsing messages easier
  - Some protocol message formats are encoded using a TLV format
    (Type, Length, Value).
    Memory management is much easier since we known immediately
    how much memory to allocate for the message. No memory is
    wasted at the end of a buffer that is only partially used.
  - The fact that TLV encodings makes memory management easier is
    one of the reasons why HTTP 1.1 is such a terrible protocol.
    That is one of the problems trying to be fixed in HTTP 2.0 where
    data is transported in LTV encoded frames.
  - Writing Partial Messages: channelOut.write(ByteBuffer) in
    non-blocking mode gives no guarantee about how many of the
    bytes in the ByteBuffer is being written. The method returns
    how many bytes were written, so it is possible to keep track
    of the number of written bytes.
  - Just like with the Message Reader, a Message Writer is used
    per channel to handle all the details.
   (partial writes, message queues, resizable buffers, protocol aware tricks,...)

-ºAll in all a non-blocking server ends up with three "pipelines" itº
 ºneeds to execute regularly:º
  - The read pipeline which checks for new incoming data from
    the open connections.
  - The process pipeline which processes any full messages received.
  - The write pipeline which checks if it can write any outgoing
    messages to any of the open connections
Path (1.7+)
- Represents a file/directory path in the FS
- Similar to java.io.File but with some minor differences.
// Ussage
import java.nio.file.Path;
import java.nio.file.Paths;

Path path = Paths.get("/var/lib/myAppData/myfile.txt");
System.out.println("Current dir:"+Paths.get(".").toAbsolutePath());
Files
- java.nio.file.Files provides several methods for manipulating FS files/directories:
- uses Path instances:

boolean pathExists = ºFiles.existsº(pathInstance,
            new LinkOption[]{ LinkOption.NOFOLLOW_LINKS});

Path newDir = ºFiles.createDirectoryº(path);

ºFiles.copyº(sourcePath, destinationPath);
ºFiles.copyº(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);

ºFiles.moveº(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);

ºFiles.deleteº(path);

Files.walkFileTree(Paths.get("data"), new FileVisitor() {
  @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
    // ...  return FileVisitResult.CONTINUE; // CONTINUE TERMINATE SKIP_SIBLINGS SKIP_SUBTREE
  }

  @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
    // ...  return FileVisitResult.CONTINUE; // CONTINUE TERMINATE SKIP_SIBLINGS SKIP_SUBTREE
  }

  @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
    // ...  return FileVisitResult.CONTINUE; // CONTINUE TERMINATE SKIP_SIBLINGS SKIP_SUBTREE
  }

  @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
    // ...  return FileVisitResult.CONTINUE; // CONTINUE TERMINATE SKIP_SIBLINGS SKIP_SUBTREE
  }
});

Asyncrhonous FileChannel 1.7+
read/write data from/to files asynchronously

Path path = Paths.get("data/test.xml");
AsynchronousFileChannel fileChannel =
    AsynchronousFileChannel.open(path, StandardOpenOption.READ);

// Reading Data, Alt 1: Via a Future
  Future operation = fileChannel.read(/*ByteBuffeR*/buffer, 0 /*start position to read from */);
  while(!operation.isDone());  // WARN: not a very efficient use of the CPU
  buffer.flip();
  byte[] data = new byte[buffer.limit()];
  buffer.get(data);
  System.out.println(new String(data));
  buffer.clear();

// Reading Data Alt 2: Via a CompletionHandler
fileChannel.read(buffer, position, buffer, new CompletionHandler() {
    @Override
    public void completed(Integer numBytesRead, ByteBuffer attachment) {
        // NOTE: attachment is a reference to the third parameter passed to .read read()
        System.out.println("numBytesRead = " + numBytesRead);
        attachment.flip();
        byte[] data = new byte[attachment.limit()];
        attachment.get(data);
        System.out.println(new String(data));
        attachment.clear();
    }

    @Override
    public void failed(Throwable exc, ByteBuffer attachment) { ...  }
});

// Writing data:
AsynchronousFileChannel fileChannel =
    AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);

// Writing Data: Alt 1: Via a Future
  ...
  Future operation = fileChannel.write(buffer, position);
  buffer.clear();
  while(!operation.isDone());

// Writing Data: Alt 2: Via CompletionHandler
...
  fileChannel.write(buffer, position, buffer, new CompletionHandler˂Integer, ByteBuffer˃() {

      @Override public void completed(Integer result, ByteBuffer attachment) { /* ... */ }
      @Override public void failed   (Throwable exc , ByteBuffer attachment) { /* ... */ }
  });

OkHTTP
https://square.github.io/okhttp/
HTTP is the way modern applications network. It’s how we exchange data & media
. Doing HTTP efficiently makes your stuff load faster and saves bandwidth.
OkHttp is an HTTP client that’s efficient by default:

- HTTP/2 support allows all requests to the same host to share a socket.
- Connection pooling reduces request latency (if HTTP/2 isn’t available).
- Transparent GZIP shrinks download sizes.
- Response caching avoids the network completely for repeat requests.

- OkHttp perseveres when the network is troublesome: it will silently recover
  from common connection problems. If your service has multiple IP addresses
  OkHttp will attempt alternate addresses if the first connect fails. This is
  necessary for IPv4+IPv6 and for services hosted in redundant data centers.
  OkHttp supports modern TLS features (TLS 1.3, ALPN, certificate pinning). It
  can be configured to fall back for broad connectivity.

- Using OkHttp is easy. Its request/response API is designed with fluent
  builders and immutability. It supports both synchronous blocking calls and
  async calls with callbacks.

- OkHttp supports Android 5.0+ (API level 21+) and Java 8+.
okIO
complements java.nio
@[https://github.com/square/okio]
- makes it much easier to access, store, and process your data.
- It started as a component of OkHttp, the capable HTTP client
  included in Android. It's well-exercised and ready to solve new problems.
Debug&Profile
JVisualVM (standard on the JDK)
@[https://visualvm.github.io/]
- displays memory usage and other useful things:
- Visual tool integrating commandline JDK tools and
  lightweight profiling capabilities.
- RºWARN: Deprecated by Flight Recorder?º
  @[https://stackoverflow.com/questions/40272599/do-java-mission-control-and-flight-recorder-deliver-same-functionality-as-visual]
  Flight Recorder works both for development and production
  while JVisualVM has performance hits

Deadlock analysis
@[https://avaldes.com/java-thread-deadlock-example-and-thread-dump-analysis-using-visualvm/]
Flight Recorder
https://www.youtube.com/watch?v=azshjd5Vsv0
- Flight Recorder is an automated black box recorder that is already
  present inside the JVM and acts to record information.
  - Mission Control is the visual console, run on a different system
  that enables operators to control the black box by evaluating metrics
  or creating performance snapshots.
- Unlike external performance monitoring systems, JFR is built directly
  into the JDK and can monitor performance in an accurate manner that 
  does not mislead readers via safe points or sampling. The result of
  JFR is accurate performance diagnostics where the act of measuring 
  incurs only about a 2% overhead. These diagnostics provide developers 
  and operators with the ability to gather actual performance data 
  instead of making guesses or pointing fingers.
  - @[http://psy-lob-saw.blogspot.com/2015/12/safepoints.html]
  - @[http://psy-lob-saw.blogspot.com/2016/02/why-most-sampling-java-profilers-are.html]
- While many profilers focus on high-level metrics, such as
  request/response load times, the concept of a "web request" does
  not exist down at the JDK’s layer. As a result the metrics provided 
  by default in JFR are aimed more towards the JVM's raw operations.
  One feature in particular is advanced garbage collection analysis. 
  Unlike common tools that simply report garbage collection statistics,
  the analysis capabilities within JFR provide details on what garbage 
  was collected and who threw it away. This feature drives two conclusions
  that improve performance:
  - developers can identify specifically what to improve, 
  - realize other when tuning garbage collection is the wrong solution.

- Free of use starting with Java 11+
- Backported to OpenJDK 8
  @[https://www.infoq.com/news/2019/11/jfr-openjdk-8/]
- (JEP 328)
- profiling tool gathering diagnostics and profiling data
- negligible performance overhead (˂1%):
-ºCan be used in productionº
CRaSH shell
Features: 
- Connect to any JVM running CRaSH through SSH, telnet or web. 
- Monitor and/or use virtual machine resources:
  JMX, database access, threads, memory usage, ...
- Embed CRaSH and expose services via a command line interface.
- Hot reload provides rapid development.
- Officially embedded as Spring Boot remote shell.

Monitoring Overview
@[http://java.sun.com/developer/technicalArticles/J2SE/monitoring/]
Eclipse Mem.Analizer
@[https://www.eclipse.org/mat/]
"""he Eclipse Memory Analyzer is a fast and feature-rich Java heap
  analyzer that helps you find memory leaks and reduce memory consumption.

  Use the Memory Analyzer to analyze productive heap dumps with hundreds of
  millions of objects, quickly calculate the retained sizes of objects, see
  who is preventing the Garbage Collector from collecting objects, run a
  report to automatically extract leak suspects.
"""

It can provide reports and warnings similar to:
  (REF: @[https://www.youtube.com/watch?v=5joejuE2rEM])
  The classloader/component "sum.misc.Launcher$AppClassLoader@0x123412"
  occupies 607,654,123(38,27%) bytes.
RºThe memory is accumulated in one instanceº of
  java.util.LinkedList$Entry loaded by 'system class loader'
SystemTap+Java
@[https://laurent-leturgez.com/2017/12/22/profiling-java-application-with-systemtap/]
[root@spark ~]# yum install systemtap systemtap-runtime-java

JAVA                                              SystemTap Profiling script
package com.premiseo;                             #!/usr/bin/env stap

import java.lang.*;                               global counter,timespent,t
import java.io.BufferedReader;
import java.io.InputStreamReader;                 probe begin {
import java.io.IOException;                         printf("Press Ctrl+C to stop profiling\n")
                                                    counter=0
class Example {                                     timespent=0
   public static void                             }
     loop_and_wait(int n)
         throws InterruptedException{             probe java("com.premiseo.Example").class("Example").method("loop_and_wait")
         System.out.println(                      {
            "Waiting "+n+"ms... Tick");             counter++
         Thread.sleep(n);                           t=gettimeofday_ms()
     }                                            }

   public static void main(String[] args) {       probe java("com.premiseo.Example").class("Example").method("loop_and_wait").return
      System.out.println("PID = "+                {
          java.lang.management.                     timespent+=gettimeofday_ms()-t
              ManagementFactory.                  }
                  getRuntimeMXBean().
                     getName().split("@")[0]);    probe end {
      System.out.println(                            printf("Number of calls for loop_and_wait method: %ld \n",    counter)
              "Press key when ready ...");           printf("Time Spent in method loop_and_wait: %ld msecs \n", timespent)
                                                  }
      try {                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        BufferedReader in =                       profiling loop_and_wait:
           new BufferedReader(                    counts number of times the
              new InputStreamReader(System.in));  loop_and_wait method has been called,
        String next = in.readLine();              and the time spent in this method execution.
      } catch (IOException ioe) {
        ioe.printStackTrace();
      }

      try {
        for (int i=0;i˂10;i++) {
           loop_and_wait(1000);
        }
      } catch (InterruptedException ie) {
        ie.printStackTrace();
      }
   }
}
Concurrent Programming
External Links
@[https://cs.nyu.edu/~lerner/spring12/Preso03-JavaPrimitives.pdf]
Concurrency Basics
- Concurrency problems arise from the desire to use CPU resources more efficiently. Non concurrent
  applications (single threaded/single process) are complete Touring machines that can potentially
  solve any problem with enough time and memory. In practice having a CPU assigned to single thread
  will be very inneficient since the CPU will stand-by while the thread is waiting for input/output
  operations. Also, many algorithms allows to split processed data in isolated regions that can be
  processed in parallel by different CPU/CPU cores
- Concurrent tries to solve the problem of multiple independents CPUs or threads accesing share
  resources (memory)
- Locks is the simples concurrent primite to protect code or data from concurrent
  access in situations where there are many threads of execution. Locks can be classified like:
  | According to lock ussage:
  |    Cooperative   A thread is encouraged (but not forced) to cooperate with other
  |                  threads by adquiring a lock before accessing the associated data
  |
  |    Mandatory     a thread trying to access an already locked resource will throw
  |                  an exception
  | _________________________________________________
  | According to lock rescheduing strategy:
  |    Blocking      The OS block the thread requesting the lock and rescheduled another thread
  |
  |    Spinlock      The thread waits in a loop until the requested lock becomes available.
  |                  It's more efficient if threads are blocked for very short time (smaller than
  |                  the time needed by the OS to reschedule another thread into the current CPU)
  |                  It's inneficient if the lock is held for a long time since a CPU core is
  |                  waisted on the spinlock loop
  | _________________________________________________
  | According to granularity: (measure of the ammount of data the lock is protecting)
  |    Coarse        Protect large segments of data (few locks). Results in less lock overhead
  |                  for a single thread, but worse performance for many threads running concurrently
  |                  (most thread will be lock-contended waiting for share resource access)
  |
  |    Fine          Protect small amounts of data. Require more lock instances reducing lock
                     contention

- Locks require CPU atomic instructions for efficient implementations suchs as
    "test-and-set", "fetch-and-add", or "compare-and-swap", whether there are blocking
    (managed by the OS) or spinlocks (managed by the thread)
- Uniprocessors can just disable interruptions to implement locks, while multiprocessors
  using shared-memory will require complex hardware and/or software support
-  ºMonitors wrap mutex-locks with condition variables (container of threads waitingº
   ºfor certain condition)º. They are implemented as thread-safe classes
monitors
-ºObject providing Mutual exclusion of threads to shared resourcesº
- simplest form of synchronization:
  alternatives include:
  - reads and writes of volatile variables
  @[https://avaldes.com/examining-volatile-keyword-with-java-threads-example/]
    typically used in applications when one thread will
    be making changes to the variables and the others all reading or
    consumers of the data. If you have multiple threads making changes to
    the data it will be best to stick with synchronized block or use
    java.util.concurrent library package.
    (volatile is actually simpler than monitors, but not universal)
    Important Points on Volatile Variables:
    - Volatile variables areºnot cached in registers or in cachesº:
     ºAll read and writes are done in main memory, never done thread-locallyº
    - Example Ussage: status flags used in spin loops
    - Volatile keywordºguarantees visibility and orderingº
  - use of classes in the java.util.concurrent package
- Monitors also have the ability to wait(block a thread) for a certain condition
  to become true, and signal other threads that their condition has been met
-ºMonitors provide a mechanism for threads to temporarily give up exclusive access inº
 ºorder to wait for some condition to be met, before regaining exclusive access and  º
 ºresuming their taskº
- each java object can be used as a monitor.
- Methods/blocks of code requiring mutual exclusion must be explicitly marked with the
Oºsynchronized keywordº:
  - The synchronized statement computes a reference to an object;
    it then attempts to perform a lock action on that object's monitor and does not
    proceed further until the lock action has successfully completed.
    After the lock action has been performed, the body of the synchronized statement
    is executed. If execution of the body is ever completed, either normally or abruptly,
    an unlock action is automatically performed on that same monitor.
  - RºWARNº: The Java programming language neither prevents nor requires detection
    of deadlock conditions.
- Instead of explicit condition variables, each monitor(/object) is equipped with
  a single wait queue in addition to its entrance queue.
- All waiting is done on this singleOºwait queueº and allOºnotify/notifyAllº
  operations apply to this queue.

ºmonitorº   enter
 ┌───┬─────── │ ──┐   - Wait sets are manipulated solely and atomically
 │  notified  v   │     through the methods
 │ ─────→         │    ºObject.waitº     : move     running thread    → wait-queue
 │   │        O   │    ºObject.notifyº   : move     thread  wait-queue → enter-queue
 │ O │        O   │    ºObject.notifyAllº: move all threads wait-queue → enter-queue
 │ O ├─────── │ ──┴─┐   Interrupt??      : put thread into to monitor enter-queue
 │ O │        v     │
 │  ←──wait   O     │  - In timed-waits  : internal action removes thread to enter-queue?
 │   │     (Running │                      after at least milliseconds plus nanoseconds
 └───┤      thread) │  - Implementations are permitted (but discouraged),
     │              │    to perform "spurious wake-ups"
     │    leave     │
     └────── │ ─────┘  O = Thread (Instruction Pointer + Stack Pointer + ...?)
             v

CountDownLatch
java.util.concurrent
@[https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html]

- Object allowing 1+ threads to wait until a 1+ operations are completed in other threads.


    A CountDownLatch is a versatile synchronization tool and can be used for a number of purposes. A CountDownLatch initialized with a count of one serves as a simple on/off latch, or gate: all threads invoking await wait at the gate until it is opened by a thread invoking countDown(). A CountDownLatch initialized to N can be used to make one thread wait until N threads have completed some action, or some action has been completed N times.

    A useful property of a CountDownLatch is that it doesn't require that threads calling countDown wait for the count to reach zero before proceeding, it simply prevents any thread from proceeding past an await until all threads could pass.

    Sample usage: Here is a pair of classes in which a group of worker threads use two countdown latches:
        The first is a start signal that prevents any worker from proceeding until the driver is ready for them to proceed;
        The second is a completion signal that allows the driver to wait until all workers have completed. 

     Ex. 1:
     class Driver { // ...

       class Worker implements Runnable {
         private final CountDownLatch OºstartSignalº;
         private final CountDownLatch BºdoneSignalº;
         Worker(CountDownLatch OºstartSignalº, CountDownLatch BºdoneSignalº) {
          Oºthis.startSignal = startSignalº;
          Bºthis.doneSignal  = doneSignalº;
         }
         public void run() {
            try {
            OºstartSignalº.await();
              doWork();
            BºdoneSignalº.countDown();   // ← Decrease count
            } catch (InterruptedException ex) {} // return;
         }

         void doWork() { ... }
       }

       void main() throws InterruptedException {
         CountDownLatch OºstartSignalº= newºCountDownLatch(1);º// ← initialized with a given count
         CountDownLatch BºdoneSignalº = newºCountDownLatch(N);º// ← "
                                                             // ← Consider alsoºCyclicBarrierº(reset after count),
         for (int i = 0; i ˂ thread_number ; ++i) { 
           new Thread(
                new Worker(
                    OºstartSignalº,
                    BºdoneSignalº
           )).start();
         }
         ...
       OºstartSignalº.countDown();      // ← Decrease count. count cannot be reset.
         doSomethingElse();
       BºdoneSignalº.await();           // ← block until current count reaches zero
                                            Thread is released. Any subsequent invocations
                                            return immediately.
       }
     }

     Ex. 2:
     - divide problem into N parts
     - describe each part with a Runnable executing a portion,
     - queue all Runnables to an Executor.
     - When all sub-parts are complete, coordinating-thread will "pass" through await.

     class Driver2 { // ...
       class WorkerRunnable implements Runnable {
         private final CountDownLatch OºdoneSignalº;
         WorkerRunnable(
            CountDownLatch OºdoneSignalº, ...) {
          Oºthis.doneSignal = doneSignalº;
         }

         public void run() {
            try {
              doneSignal.countDown();
            } catch (InterruptedException ex) {} // return;
         }

         void doWork() { ... }
       }
       void main() throws InterruptedException {
         CountDownLatchOºdoneSignalº= new CountDownLatch(N);
         Executor e = ...

         for (int i = 0; i ˂ N; ++i) // create and start threads
           e.execute(new WorkerRunnable(OºdoneSignalº, i));

       OºdoneSignalº.await();           // wait for all to finish
       }
     }
Scheduling threads
Runnables/Callables
Executors
@[https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html]
 ┌────────────┐ │ ┌───────────────┐  │
 │˂˂Runnable˃˃│ │ │˂˂Callable˂V˃˃˃│  │          ˂˂Executor˃˃
 │────────────│ │ │───────────────│  │               ↑
 │+run()      │ │ │+call()        │  │       ˂˂ExecutorService˃˃  ← managed collection of threads
 └────────────┘ │ └───────────────┘  │               ↑              available to execute tasks
       ^        │ (util.concurrent)  │    ┌──────────┴──────────────┐
       │        │                    │    │                         │
 ┌────────────┐ │ Allows to return   │ AbstractExecutorService  ˂˂ScheduledExecutorService˃˃
 │   Thread   │ │ a result/Exception │    ↑                         ↑
 │────────────│ │ to the thread      │ ThreadPoolExecutor           │
 │+run()      │ │ triggering the     │    ↑                         │
 │+start()    │ │ Callable           │ ScheduledThreadPoolExecutor ─┘
 │+sleep()    │ │                    │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 │....        │ │                    │ Prefered to "old" java.util.timer:
 │────────────│ │                    │  - Timer can be sensitive to system clock changes 
 └────────────┘ │                    │  - Timer has only one execution thread. Long-running
                                          task can delay other tasks. ScheduledThreadPoolExecutor 
                                          can be configured with "N" threads.
                                        - Runtime exceptions thrown kill the Timer thread.
                                          ScheduledThreadExecutor catches Runtime Ex,
                                          and allows to handle them by overriding afterExecute 
                                          method from ThreadPoolExecutor). Onley the Task throwing
                                          the exception will be canceled.

- ˂˂ExecutorService˃˃(Thread Pool) ussage:
  - Alt 1: use an implementation of the interface,
           such as ThreadPoolExecutor or ScheduledThreadPoolExecutor.
           an the ˂˂ExecutorService˃˃Instance.execute(/*Runnable */runnableInstance)
           to add a Runnable task to thread pool.
           -  Will execute the task at some time in the
              future in a new thread, in a thread pool, or
              in the calling thread, depending on the implementation
           ˂˂java.util.concurrent.ExecutorService˃˃
           + public     void      shutdown(); // Initiates orderly shutdown of pool
           + public ˂T˃ Future˂T˃ submit(Callable˂T˃ task); // schedule callable task for execution

  - Alt 2: Use factory methods in the 'Executors' class:
          - Write worker thread class implementing ˂˂Runnable˃˃ run()
          Executors.newSingleThreadExecutor()
          Executors.newFixedThreadPool(int numThreads)
          Executors.newCachedThreadPool(): // ← unbounded pool, with automatic reclamation
          Executors.newSingleThreadScheduledExecutor()
          Executors.newScheduledThreadPool(int size)

   _______  __    _    __  __ ____  _     _____ ____
  | ____\ \/ /   / \  |  \/  |  _ \| |   | ____/ ___|
  |  _|  \  /   / _ \ | |\/| | |_) | |   |  _| \___ \
  | |___ /  \  / ___ \| |  | |  __/| |___| |___ ___) |
  |_____/_/\_\/_/   \_\_|  |_|_|   |_____|_____|____/

ºEx: CallableThreadPoolTestº                                                 ºEx: ThreadPoolTestº
 import java.util.concurrent.Callable;                                       │import java.util.concurrent.ExecutorService;
 import java.util.concurrent.*;                                              │import java.util.concurrent.Executors;
 ...                                    ┌──→public classºMyCallableThreadº   │...
 int numWorkers = 10;                   │  │    implements Callable˂String˃{ │ExecutorService pool =
 ExecutorService pool =                 │  │  MyCallableThread(int id)       │  Executors.newFixedThreadPool(10);
     Executors.newCachedThreadPool();   │  │  {                              │MyWorker[] workers =
ºMyCallableThread workers[]º =       ───┘  │    ...                          │  new MyWorker[numWorkers];
     new MyCallableThread[numWorkers];     │  }                              │for (int i = 0; i ˂ numWorkers; ++i)
 Future futures[] = new Future[numWorkers];│                                 │  pool.execute(new MyWorker(i+1));
                                           │  public String call() {         │pool.shutdown();
 for (int i = 0; i ˂ numWorkers; ++i) {    │    Thread.sleep(1000));
    workers[i] = new MyCallableThread(i+1);│    return ""+id;
    futures[i] = pool.submit(workers[i]);  │  }
 }                                         │}
 for (int i = 0; i ˂ numWorkers; ++i) {
   try {
     System.out.println(
       futures[i].get() + " ended");
   } catch (InterruptedException ex) {
     ex.printStackTrace();
   } catch (ExecutionException ex) {
     ex.printStackTrace();
   }
 }
Completable Future
@[https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html]
(Java 8+)
- A Future that may be explicitly completed (setting its value and status),
  and may be used as a CompletionStage, supporting dependent functions and
  actions that trigger upon its completion.
- When two or more threads attempt to complete, completeExceptionally, or
  cancel a CompletableFuture, only one of them succeeds.

ºBarriers (OºallOf*):
  CompletableFuture˂Void˃[] future_list
    = new CompletableFuture[list.size()];
  int idx=0;
  log.info("Connecting plugins ...");
  for (Object el : list) {
    final CompletableFuture˂Void˃
      connectFuture = new CompletableFuture˂˃();
    asyncMethod(connectFuture);
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    The async Method at some moment must call the
    complete()
    ...
  }
  return CompletableFuture. OºallOfº(future_list);

Extracted from:
@[http://www.baeldung.com/java-completablefuture]
In asynchronous computation, actions are represented as callbacks, handling errors might occur at any step.

Java 5+: Future: Represent an asynchronous computation
Java 8+: CompletableFuture : Extends Future with methods to combine and handle errors
                            Extends the CompletionStage interface
                              - Contract for an asynchronous computation step that
                                can be combined with other steps.
                            About 50 different methods for composing, combining, executing async computation

Using CompletableFuture as a Simple Future (no-arg constructor)

In the example below we have a method that creates a CompletableFuture instance, then spins off some computation in another thread and returns the Future immediately.

  1  public Future calculateAsync() throws InterruptedException {
  2      Future result = new CompletableFuture˂˃();
  3
  4      Executors.newCachedThreadPool().submit(() -˃ {
  5          Thread.sleep(500);
  6          completableFuture.complete("Hello");
  7          return null;
  8      });
  9
  10     return completableFuture;
  11 }
  Line 2: Alternatively when the result of computation is known:
          Future result = CompletableFuture.
             completedFuture("Hello");

  Line 6: Alternatively completableFuture.cancel(false);
  Line 5: any other mechanism can be used to compute


  1 Future completableFuture = calculateAsync();
  2
  3 // ...
  4
  5 String result = completableFuture.get();
  6 assertEquals("Hello", result);

Line 5: get() blocks until .complete("...") is called in other thread
Line 5: get()can raise
           ExecutionException: error during computation
           InterruptedException: thread executing method interrupted

4. CompletableFuture with Encapsulated Computation Logic (runAsync -˂˂Runnable˃˃-, supplyAsync -˂˂Supplier˃˃-)

˂˂Supplier˃˃: generic functional interface with single method (zero arguments, returns value)

  1 CompletableFuture˂String˃ future
  2   = CompletableFuture.supplyAsync(/*supplier lambda*/ () -˃ "Hello")
  3 .thenApply(/* "processor" lambda */ s -˃ s + " World") /* returns CompletableFuture */;
  4 .thenAccept(/*consumer lambda */
  5    s -˃ System.out.println("Computation returned: " + s));
    Line 4: Alternatively (ignrore result)
    .thenRun(/*Runnable lambda*/ () -˃ System.out.println("Computation finished."));

5. Combining Futures (monadic design pattern in functional languages)

  1 CompletableFuture˂String˃ completableFuture
  2   = CompletableFuture.supplyAsync(() -˃ "Hello")
  3     .thenCompose(
  4           s -˃ CompletableFuture.supplyAsync(() -˃ s + " World"));
  4
  5 assertEquals("Hello World", completableFuture.get());

6. Execute two independent Futures and do something with their results

  1 CompletableFuture future
  2   = CompletableFuture.supplyAsync(() -˃ "Hello")
  3     .thenCombine(CompletableFuture.supplyAsync(
  4       () -˃ " World"), (s1, s2) -˃ s1 + s2));
  5
  6 assertEquals("Hello World", future.get());

(Simpler case - nothing to do with resulting value-)
  2   = CompletableFuture.supplyAsync(() -˃ "Hello")
  3   .thenAcceptBoth(CompletableFuture.supplyAsync(
  4      () -˃ " World"), (s1, s2) -˃ log(s1 + s2));

7. Running Multiple Futures in Parallel:  wait for all to execute and process combined results

  1  CompletableFuture˂String˃ future1
  2    = CompletableFuture.supplyAsync(() -˃ "Hello");
  3  CompletableFuture˂String˃ future2
  4    = CompletableFuture.supplyAsync(() -˃ "Beautiful");
  5  CompletableFuture˂String˃ future3
  6    = CompletableFuture.supplyAsync(() -˃ "World");
  7
  8  CompletableFuture˂Void˃ combinedFuture
  9    = CompletableFuture.allOf(future1, future2, future3);
  10
  11 // ...
  12
  13 combinedFuture.get();
  14
  15 String combined = Stream.of(future1, future2, future3)
  16   .map(CompletableFuture::join)
  17   .collect(Collectors.joining(" "));
  18 assertEquals("Hello Beautiful World", combined);

    Line 16: join() is similar to get, but throws unchecked exception if the Future does not complete normally.

8. Handling Errors

   Instead of catching an exception in a syntactic block, the CompletableFuture class allows you to handle it in a special handle method. This method receives two parameters: a result of a computation (if it finished successfully) and the exception thrown (if some computation step did not complete normally).



Capture async exception:

  1  CompletableFuture˂String˃ completableFuture
  2    =  CompletableFuture.supplyAsync(() -˃ {
  3        ... if(errorDetected)
  4               throw new RuntimeException("Computation error!");
  6        return "Hello ";
  7    })}).handle((s, t) -˃ s != null ? s : "Hello, Stranger!");
  8
  9  assertEquals("Hello, Stranger!", completableFuture.get());
Alt:
  1  completableFuture.completeExceptionally(
  2    new RuntimeException("Calculation failed!"));
  3  ...
  4  completableFuture.get(); // ExecutionException

9. Async Methods
 - The methods without the Async postfix run next execution stage using a calling thread.

 - The Async method without the Executor argument runs a step using the common fork/join pool implementation of Executor
   that is accessed with the ForkJoinPool.commonPool() method.

 - The Async method with an Executor argument runs a step using the passed Executor.

 Ex.: process result of computation with a Function instance
  1 CompletableFuture completableFuture
  2   = CompletableFuture.supplyAsync(() -˃ "Hello");
  3
  4 CompletableFuture future = completableFuture
  5   .thenApplyAsync(s -˃ s + " World");
  6
  7 assertEquals("Hello World", future.get());

    Line 5: under the hood the application of a function is wrapped into a ForkJoinTask instance
    (for more information on the fork/join framework, see the article ?Guide to the Fork/Join Framework in Java?).
    This allows to parallelize your computation even more and use system resources more efficiently.
Guava ListenableFuture
@[https://github.com/google/guava/wiki/ListenableFutureExplained]
- Concurrency is a hard problem, but it is significantly simplified by
  working with powerful and simple abstractions. To simplify matters,
  Guava extends the Future interface of the JDK with ListenableFuture.

- """We strongly advise that you always use ListenableFuture instead
  of Future in all of your code, because:
  - Most Futures methods require it.
  - It's easier than changing to ListenableFuture later.
  - Providers of utility methods won't need to provide Future and ListenableFuture
      variants of their methods.


Listenable vs
CompletableFutures
@[https://stackoverflow.com/questions/38744943/listenablefuture-vs-completablefuture]
          ListenableFuture                           │               CompletableFuture
─────────────────────────────────────────────────────┼───────────────────────────────────────────────────
                                                     │ It is different from ListenableFuture in that it
                                                     │ can be completed from any thread that wants it to complete
─────────────────────────────────────────────────────┼───────────────────────────────────────────────────
ListenableFuture listenable = service.submit(...);   │ CompletableFuture completableFuture =
  Futures.addCallback(listenable,                    │     new CompletableFuture();
                      new FutureCallback˂Object˃() { │ completableFuture.whenComplete(new BiConsumer() {
    @Override                                        │   @Override
    public void onSuccess(Object o) {                │   public void accept(Object o, Object o2) {
        //handle on success                          │       //handle complete
    }                                                │   }
                                                     │ }); // complete the task
    @Override                                        │ completableFuture.complete(new Object())
    public void onFailure(Throwable throwable) {     │
       //handle on failure                           │ When a thread calls complete on the task,
    }                                                │ the value received from a call to get() is
  })                                                 │ set with the parameter value if the task is
                                                     │ not already completed.

  ..."CompletableFuture is dangerous because it exposes ºcompeteº methods."
  ..."CompletableFuture would have been good if it extended Future and did not expore
      toCompletableFuture,... and they could have named it something
      meaningful like ChainableFuture "
Loom Prj
Ligthweight
threads
@[https://developers.redhat.com/blog/2019/06/19/project-loom-lightweight-java-threads/]
@[https://openjdk.java.net/jeps/353]

Project Loom's mission is to make it easier to write, debug, profile and
maintain concurrent applications meeting today's requirements. Threads,
provided by Java from its first day, are a natural and convenient concurrency
construct (putting aside the separate question of communication among threads
) which is being supplanted by less convenient abstractions because their
current implementation as OS kernel threads is insufficient for meeting
modern demands, and wasteful in computing resources that are particularly
valuable in the cloud. Project Loom will introduce fibers as lightweight,
efficient threads managed by the Java Virtual Machine, that let developers
use the same simple abstraction but with better performance and lower
footprint. We want to make concurrency simple(r) again! A fiber is made of
two components — a continuation and a scheduler. As Java already has an
excellent scheduler in the form of ForkJoinPool, fibers will be implemented
by adding continuations to the JVM.

RELATED: http://www.linuxplumbersconf.org/2013/ocw/system/presentations/1653/original/LPC%20-%20User%20Threading.pdf

@[https://www.infoq.com/presentations/continuations-java/]
Ron Pressler discusses and compares the various techniques of dealing with concurrency
and IO in both:
- pure functional (monads, affine types)
- imperative      (threads, continuations, monads, async/await)
and shows why delimited continuations are a great fit for the imperative style.

Bio
Ron Pressler is the technical lead for Project Loom, which aims to add delimited
continuations, fibers and tail-calls to the JVM

Quasar
Java Fibers
- fast threads for java and Kotlin
@[http://docs.paralleluniverse.co/quasar/]

NOTE: To be superseded by Prj. Loom?
Extracted from @[https://github.com/puniverse/quasar/issues/305]
My understanding is that Ron is currently busy working for/with Oracle on
project Loom which should bring "native" Fiber/lightweight continuation
support directly into JVM without the need of auxiliary library like Quasar.
fast Inter-thread communication
@[https://www.infoq.com/articles/High-Performance-Java-Inter-Thread-Communications]
Async/Reactive Programming
Summary
addition of lambda expressions in Java 8 created opportunities for functional
APIs in Java. This is a boon for non-blocking applications and continuation
style APIs — as popularized by CompletableFuture and ReactiveX, that allow
declarative composition of asynchronous logic. At the programming model level
Java 8 enabled Spring WebFlux to offer functional web endpoints alongside
with annotated controllers.

The term "reactive" refers to programming models that are built around
reacting to change — network component reacting to I/O events, UI controller
reacting to mouse events, etc. In that sense non-blocking is reactive because
instead of being blocked we are now in the mode of reacting to notifications
as operations complete or data becomes available.

Spring Reactive Streams is a small spec, also adopted in Java 9, that defines
the interaction between asynchronous components with back pressure. For
example a data repository — acting as Publisher, can produce data that an
HTTP server — acting as Subscriber, can then write to the response. The main
purpose of Reactive Streams is to allow the subscriber to control how fast or
how slow the publisher will produce data.

Reactive Streams plays an important role for interoperability. It is of
interest to libraries and infrastructure components but less useful as an
application API because it is too low level. What applications need is a
higher level and richer, functional API to compose async logic — similar to
the Java 8 Stream API but not only for collections. This is the role that
reactive libraries play.
java.util.concurrent.Flow
@[https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html]
- JDK 1.9+
- Reactive Streams was adopted by the JDK in the form of the java.util.concurrent.Flow API.
- It allows two different libraries that support asynchronous streaming to connect to each other,
    with well specified semantics about how each should behave, so that backpressure, completion, cancellation
    and error handling is predictably propagated between the two libraries.
- There is a rich ecosystem of open source libraries that support Reactive Streams,
    and since its inclusion in JDK9, there are a few in development implementations that are
    targetting the JDK, including the incubating JDK9 HTTP Client,
    and the Asynchronous Database Adapter (ADBA)
    effort that have also adopted it
- (See also What can Reactive Streams offer to EE4J)
RxJava
@[https://github.com/ReactiveX/RxJava]

ºObservable/Operators/Observersº
@[http://reactivex.io/documentation/contract.html]
@[http://reactivex.io/documentation/observable.html]
                                         ⇑
                                    ˂˂Subscriber˃˃
                                    unsubscribe  : - Observable can opt to stop
                                                   event-emission if no more clients
                                                   are subcribed
 Loop-of-Observable-emitted-events:                - unsubscription will cascade back
    Observable → ˂˂IObserver˃˃: onNext(event)      through the chain of operators
    observer → observer  : handle event            applying to associated Observable.
    ^^^^^^^^
    also called
    "subscriber"
    "watcher"
    "reactor"  ("reactor pattern")
 end-loop
 Observable → ˂˂handlerInstance˃˃: onCOmpleted()
 observer → observer  : handle event

 RºWARN:º There is no canonical naming standard in RXJava


 ºObservable˂T˃º → operator1 → ... → operatorN → ºObserverº
Oºpushesºobjects                                  Subscribes to
 (events) from                                    the observable
 any source                                       events
 (ddbb, csv,...)                                  .onNext()     
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   .onCompleted()
            Learning which operators to use       .onError()    
            for a situation and how to combine    .onSubscribe(Disposable d);
            them is the key to master RxJava      ^
            them is the key to mastering RxJava   │
┌─────────────────────────────────────────────────┘
├─onSubscribe(Disposible): Free any resources created by the rxJava pipeline.
├─onNext()     : passes each item, one at a time,   to the ºObserverº
├─onCompleted(): communicates a completion event    to the ºObserverº
└─onError()    : communicates an error up the chain to the ºObserverº
                 where the Observer typically defines how to handle it.
                 Unless retry() operator is used to intercept the error,
                 the Observable chain typically terminates, and no
                 more emissions will occur.
                 See also Gºoperators 'Catch' and 'Retry'º

By default, Observables execute work on the immediate thread,
which is the thread that declared the Observer and subscribed it.
Not all Observables will fire on the immediate thread, (Observable.interval(),...)

ºcreating a source Observable:º
  Observable˂String˃ source00 = Observableº.justº("value1",...,"valueN");
  Observable˂String˃ source00 = Observableº.fromCallableº(() -˃ 1/0);
                                            ^^^^^^^^^^^^        ^^^
                                            Similar to .just() but errors
                                            are captured by the rxJava "pipeline"

  Observable˂String˃ source01 = Observableº.createº( emitter -˃ 
  {
        try {
    emitterº.onNextº(myList.get(0));
    emitter .onNext (myList.get(1));
    ...
    emitterº.onComplete()º; // ← Optional
        } catch(Throwable e) {
    emitterº.onError(e)º;
        }
  } );
  Observable˂String˃  source02 = Observableº.fromIterableº(myIterableList);
  Observable˂Integer˃ source03 = Observableº.rangeº(1,10);
  Observable˂String˃  source04 = Observableº.intervalº(1, TimeUnit.SECONDS);
                                             ^^^^^^^^
                                             Since it operates on a timer →
                                             needs to run on separate thread
                                             and will run on the computation
                                             Scheduler by default

  Observable˂String˃  source05 = Observableº.fromFutureº(myFutureValue);
  Observable˂String˃  source06 = Observableº.emptyº();
                                             ^^^^^
                                             calls onComplete() and ends

  Observable˂String˃  source07 = Observableº.deferº( () -˃ Observable.range(start,count));
                                             ^^^^^
                                      Advanced factory pattern.
                                      allows a separate state for each observer
  Observable˂String˃  source08 = Observableº.fromCallableº( () -˃ Observable.range(start,count));

ºcreating Single/Maybe/Completable "Utility" Observables:º
 ┌─────────────────────────────┬────────────────────────────────┬─────────────────────────────────┐
 │ Single.just("Hello")        │ Maybe.just("Hello")            │ Completable.fromRunnable(       │
 │ .subscribe(...);            │   .subscribe(...);             │   () -˃ runProcess() )          │
 │                             │                                │ .subscribe(...);                │
 ├─────────────────────────────┼────────────────────────────────┼─────────────────────────────────┤
 │ Emits a single item         │ Emits (or not)a single item    │  does not receive any emissions │
 ├─────────────────────────────┼────────────────────────────────┼─────────────────────────────────┤
 │ºSingleObserverº             │ ºMaybeObserverº                │ ºCompletableObserverº           │
 │ .onSubscribe(Disposable d); │  .onSubscribe(Disposable d);   │  .onSubscribe(Disposable d);    │
 │ .onSuccess(T value);        │  .onSuccess(T value);          │  .onComplete();                 │
 │ .onSuccess(Throwable error);│  .onSuccess(Throwable error);  │  .onError(Throwable error);     │
 │                             │  .onComplete();                │                                 │
 └─────────────────────────────┴────────────────────────────────┴─────────────────────────────────┘

ºCreate Test-oriented observablesº
   Observableº.neverº();
   Observableº.errorº();

ºDerive Observables from source:º
Observable˂Integer˃ lengths  =  sourceº.mapº   (String::length);
Observable˂Integer˃ filtered = lengthsº.filterº(i -˃ i  = 5);

ºcreating an Observer:º
(Lambdas in the source Observable .subscribe can be used in place)
Observer˂Integer˃ myObserver = new Observer˂Integer˃() {
  @Override public void onSubscribe(Disposable d) { //... }
  @Override public void onNext(Integer value)     { log.debug("RECEIVED: " + value); }
  @Override public void onError(Throwable e)      { e.printStackTrace();}
  @Override public void onComplete()              { log.debu("Done!"); }
};

Cold/Hot Observables
- Cold: - Repeat the same content to different observers.
        - Represent sort-of inmmutable data.
        - A "cold" Observable waits until an observer subscribes to it
          an observer is guaranteed to see the whole sequence of events
- Hot : "Broadcast" to all observers at the same time.
        - A "hot" Observable may begin emitting items as soon as it is created.
        - An observer connecting "later" will loose old emissions.
        - Representºreal-time eventsº. They are time-sensitive.
        - Emissions will start when first observers calls connect().
        - a cold/hot observable can generate a new hot observable by 
          calling publish() that will return a hot ConnectableObservable.
          Helpful to avoid the replay of data on each subscrived Observer.

        - NOTE: A "Connectable" Observable: does NOT begin emitting items
            until its Connect method is called, whether or not any observers
            have subscribed to it.

About Nulls
In RxJava 2.0, Observables ☞GºNO LONGER SUPPORT EMITTING null VALUESº☜ !!!

Decision  Tree
@[http://reactivex.io/documentation/operators.html#tree]
Alphabetical List of Observable Operators
@[http://reactivex.io/documentation/operators.html#alphabetical

Core API
-ºrx.Observableº"==" [Java 8 Stream + CompletableFuture + "Back-presure" measures ]
  @[http://reactivex.io/documentation/observable.html]    └──────────────┬──────┘
                                                                         │
                                                          probably an intermediate 
                                                          buffer for incomming/outgoing 
                                                          messages that acts async. 
                                                          when not full, and sync when 
                                                          full.
  - ºrx.Singleº: specialized version emiting a single item

-ºrx.Operatorsº:
  - Compose Observables in a chain
  - gives the real "reactive" power
  - operators allow to transform, combine, manipulate, and work
    with the sequences of items emitted by Observables.
  - declarative programming
    -ºAVOID THE THE DRAWBACKS OF CALLBACK-NESTING("callback hell")º
    - Most operators operate on an Observable and return an Observable.
      Each operator in the chain modifies the Observable that results
      from the operation of the previous operator. Order matters.
      (the Builder Pattern, also supported, is non-ordered)
-ºrx.Subjectº:
@[http://reactivex.io/documentation/subject.html]
  sort of "bridge or proxy" is available in some implementations
  that acts both as an observer and as an Observable.
-ºrx.Schedulerº:
@[http://reactivex.io/documentation/scheduler.html]
  - Needed when using multithreading into the
    cascade of Observable operators.
  - By default, the chain of Observables/operators
    will notify its observers ºon the same threadº
   ºon which its Subscribe method is calledº
  Operator|SubscribeOn         |ObserveOn
  --------+--------------------+---------
          |sets an Scheduler on|sets an Scheduler used
          |which the Observable|by the Observable to
          |should operate.     |send notifications to
          |                    |its observers.
  Scheduler "==" Thread

External links:
- Rx Workshop: Introduction
 @[https://channel9.msdn.com/Series/Rx-Workshop/Rx-Workshop-Introduction]
- Introduction to Rx: IObservable
 @[http://introtorx.com/Content/v1.0.10621.0/02_KeyTypes.html#IObservable]
- Mastering observables (from the Couchbase Server documentation)
 @[https://developer.couchbase.com/documentation/server/3.x/developer/java-2.0/observables.html]
- 2 minute introduction to Rx by Andre Staltz (“Think of an Observable as an asynchronous immutable array.”)
 @[https://medium.com/@andrestaltz/2-minute-introduction-to-rx-24c8ca793877]
- Introducing the Observable by Jafar Husain (JavaScript Video Tutorial)
 @[https://egghead.io/lessons/rxjs-introducing-the-observable]
- Observable object (RxJS) by Dennis Stoyanov
 @[http://xgrommx.github.io/rx-book/content/observable/index.html]
- Turning a callback into an Rx Observable by @afterecho
 @[https://afterecho.uk/blog/turning-a-callback-into-an-rx-observable.html]

Operator classification 1
ºOperators creating new Observablesº
@[http://reactivex.io/documentation/operators.html#creating]
   ºCreate   º create Observable from scratch programmatically
   ºDefer    º do not create the Observable until the observer subscribes,
               and create a fresh Observable for each observer
   ºEmpty    º create Observables that have very precise and limited behavior
   ºNever    º   "                                                             
   ºThrow    º   "                                                             
   ºFrom     º create some object or data structure 
   ºInterval º create Observable that emits a sequence of integers spaced
               by a particular time interval
   ºJust     º convert an object or a set of objects into an Observable that emits that or those objects
   ºRange    º create an Observable that emits a range of sequential integers
   ºRepeat   º create an Observable that emits a particular item or sequence of items repeatedly
   ºStart    º create an Observable that emits the return value of a function
   ºTimer    º create an Observable that emits a single item after a given delay

ºOperators Transforming Items:º
@[http://reactivex.io/documentation/operators.html#transforming]
   ºBuffer   º periodically gather items from input into bundles and emit
               these bundles rather than emitting the items one at a time

   ºFlatMap  º transform the items emitted by an Observable into Observables,
               then flatten the emissions from those into a single Observable
   ºGroupBy  º divide an Observable into a set of Observables that each emit a
               different group of items from the original Observable, 
             Gºorganized by keyº
   ºMap      º transform each input-item by applying a function
   ºScan     º apply a function to each item emitted by an Observable, 
               sequentially, and emit each successive value
   ºWindow   º periodically subdivide items from an Observable into 
               Observable windows and emit these windows rather than emitting
               the items one at a time

ºOperators selectively filtering emitted events from a source Observableº
@[phttp://reactivex.io/documentation/operators.html#filtering]
   ºDebounce º only emit an item from an Observable if a particular timespan has passed 
               without it emitting another item
   ºDistinct º suppress duplicate items emitted by an Observable
   ºElementAtº emit only item n emitted by an Observable
   ºFilter   º emit only those items from an Observable that pass a predicate test
   ºFirst    º emit only the first item, or the first item that meets a condition, from an Observable
   ºIgnoreElements º do not emit any items from an Observable but mirror its termination notification
   ºLast     º emit only the last item emitted by an Observable
   ºSample   º emit the most recent item emitted by an Observable within periodic time intervals
   ºSkip     º suppress the first n items emitted by an Observable
   ºSkipLast º suppress the last n items emitted by an Observable
   ºTake     º emit only the first n items emitted by an Observable
   ºTakeLast º emit only the last n items emitted by an Observable


ºOperators Combining multiple source Observables into a new single Observableº
@[http://reactivex.io/documentation/operators.html#combining]
   ºAnd      º combine sets of items emitted by two or more Observables by means 
   ºThen     º of Pattern and Plan intermediaries
   ºWhen     º

   ºCombineLatest º when an item is emitted by either of two Observables, combine the 
               latest item emitted by each Observable via a specified function and 
               emit items based on the results of this function
   ºJoin     º combine items emitted by two Observables whenever an item from one 
               Observable is emitted during a time window defined according to an 
               item emitted by the other Observable
   ºMerge    º combine multiple Observables into one by merging their 
               emissions
   ºStartWithº emit a specified sequence of items before beginning to emit the 
               items from the source Observable
   ºSwitch   º convert an Observable that emits Observables into a single 
               Observable that emits the items emitted by the most-recently-
               emitted of those Observables
   ºZip      º combine multiple Observables emissions together via a function 
               function → emit single items for each input tuple

ºOperators handling Errors and helping to recover from error-notificationsº
@[http://reactivex.io/documentation/operators.html#error]
   ºCatch º recover from an onError notification by continuing the sequence without error
   ºRetry º if a source Observable sends an onError notification, resubscribe to it
            in the hopes that it will complete without error

ºUtility Operators "toolbox"º
@[http://reactivex.io/documentation/operators.html#utility]
   ºDelay     º shift the emissions from an Observable forward in time by a particular amount
   ºDo        º register an action to take upon a variety of Observable lifecycle events

   ºMaterialize  º represent both the items emitted and the notifications sent
   ºDematerializeº  as emitted items, or reverse this process

   ºObserveOn º specify the scheduler on which an observer will observe this Observable
   ºSerialize º force an Observable to make serialized calls and to be well-behaved
   ºSubscribe º operate upon the emissions and notifications from an Observable
   ºSubscribeOn º specify the scheduler an Observable should use when it is subscribed to
   ºTimeIntervalº convert an Observable that emits items into one that emits indications
                  of the amount of time elapsed between those emissions
   ºTimeout   º mirror the source Observable, but issue an error notification if a
                particular period of time elapses without any emitted items
   ºTimestamp º attach a timestamp to each item emitted by an Observable
   ºUsing     º create a disposable resource that has the same lifespan as the Observable

ºConditional and Boolean Operators evaluating one or moreº
  Observables or items emitted by Observables
@[http://reactivex.io/documentation/operators.html#conditional]
   ºAll       º determine whether all items emitted by an Observable meet some criteria
                Mathematical and Aggregate Operators
@  ºAmb       º given two or more source Observables, emit all of the items from only the
                first of these Observables to emit an item
              @[http://reactivex.io/documentation/operators.html#mathematical]
   ºContains º determine whether an Observable emits a particular item or not
               Average, Concat, Count, Max, Min, Reduce, and Sum
C  ºDefaultIfEmptyº emit items from the source Observable, or a default item if the 
               source Observable emits nothing  onverting Observables
@  ºSequenceEqual º determine whether two Observables emit the same sequence of items
   ºSkipUntil º discard items emitted by an Observable until a second Observable emits an item To
C  ºSkipWhile º discard items emitted by an Observable until a specified condition becomes false 

ºConnectable Observable Operatorsº
[http://reactivex.io/documentation/operators.html#connectable]
@  ºTakeUntil º discard items emitted by an Observable after a second Observable emits an item or terminates
   ºTakeWhile º discard items emitted by an Observable after a specified condition becomes false
   ºConnect   º
   ºPublish   º
   ºRefCount  º
   ºReplay    º

ºMathematical and Aggregate Operatorsº
- Operators that operate on the entire sequence of items emitted by an Observable
   ºAverage   º calculates the average of numbers emitted by an Observable and emits this average
   ºConcat    º emit the emissions from two or more Observables without interleaving them
   ºCount     º count the number of items emitted by the source Observable and emit only this value
   ºMax       º determine, and emit, the maximum-valued item emitted by an Observable
   ºMin       º determine, and emit, the minimum-valued item emitted by an Observable
   ºReduce    º apply a function to each item emitted by an Observable, sequentially, and emit the final value
   ºSum       º calculate the sum of numbers emitted by an Observable and emit this sum

ºBackpressure Operatorsº
a variety of operators that enforce particular flow-control policies
    @[http://reactivex.io/documentation/operators/backpressure.html]
- backpressure operators ºstrategiesº for coping with Observables that produce items more
  rapidly than their observers consume them

ºConnectable Observable Operatorsº
Specialty Observables that have more precisely-controlled subscription dynamics
   ºConnect º instruct a connectable Observable to begin emitting items to its subscribers
   ºPublish º convert an ordinary Observable into a connectable Observable
   ºRefCountº make a Connectable Observable behave like an ordinary Observable
   ºReplay  º ensure that all observers see the same sequence of emitted items, even if they
              subscribe after the Observable has begun emitting items

ºOperators to Convert Observablesº
   ºToº       convert an Observable into another object or data structure

Operator classification 2
- Basic Operators:
  - Suppressing operators:
    - filter, take, skip, takeWhile/skipWhile, distinct, distinctUntilChanged
  - Transforming operators:
    - map, cast, startWith, defaultIfEmpty, switchIfEmpty, sorted, deplay,repeat, scan
  - Reducing operators:
    - count, reduce, all, any, contains
  - Collection operators:
    - toList, toSortedList, toMap, toMultiMap, collect
  - Error recovery Operators
    - onErrorReturn, onErrorReturnItem, onErrorResumeNext, retry
  - Action ("stream life-cicle") Operators:
    - doOnNext, doOnComplete, doOnError, doOnSubscribe, doOnDispose
- Combining Observables:
  - Merging:
    - merge, mergeWith
    - flatMap
  - Concatenation:
    - concat, concatWith
    - concatMap
  - Ambiguous:
    - amb
  - Zipping
  - Combine Latest:
    - withLatestFrom
  - Grouping:
    - groupBy
 
- Multicasting, Replaying and Caching:
  ( Multicasting is helpful in preventing redundant work being done by multiple
    Observersand instead makes all Observers subscribe to a single stream, 
    at least to the point wherethey have operations in common)
  - "Hot" operators. (TODO)
  - Automatic connection:
    - autoConnect, refCount, share
  - replay
  - cache

-Subjects
  - Justlike mutable variables are necessary at times even though you 
    should strive forimmutability, Subjects are sometimes a necessary tool
    to reconcile imperative paradigmswith reactive ones.
  - PublishSubject
  - Serializin Subject
  - BehaviourSubject
  - ReplaySubject
  - AsyncSubject
  - UnicastSubject
Implementing new Operators:
@[http://reactivex.io/documentation/implement-operator.html]

Awaitility
Sync-the-Async
Java DSL
@[https://github.com/awaitility/awaitility]

Testing asynchronous systems is hard. Not only does it require handling threads,
timeouts and concurrency issues, but the intent of the test code can be obscured
by all these details. Awaitility is a DSL that allows you to express expectations
of an asynchronous system in a concise and easy to read manner. For example:

@Test
public void updatesCustomerStatus() {
  // Publish an asynchronous message to a broker (e.g. RabbitMQ):
  messageBroker.publishMessage(updateCustomerStatusMessage);
  // Awaitility lets you wait until the asynchronous operation completes:
  await().atMost(5, SECONDS).until(customerStatusIsUpdated());
  ...
}
Spring Reactor
Spring-Async
@[https://ordina-jworks.github.io/reactive/2016/12/12/Reactive-Programming-Spring-Reactor.html]
@[https://spring.io/blog/2013/05/13/reactor-a-foundation-for-asynchronous-applications-on-the-jvm]
@[https://spring.io/guides/gs/async-method/]
"""Why Reactor when there's already RxJava2?
   RxJava2 is java 6 while for Reactor the Spring team decided to go all in
   and focus only on Java 8. This means that you can make use of all the new
   and fancy Java 8 features.

   If you are going to use Spring 5, Reactor might be the better option.

   But if you are happy with your RxJava2, there is no direct need to migrate to Reactor."""

VertX
Who-is-Who
(Forcibly incomplete but still quite pertinent list of core developers and companies)
Tim Fox     :  Initiated VertX in 2012
Julien Viet :  Project lead (as of 2020), RedHat, Marseille
             @[https://github.com/vietj]
             @[http://blog.julienviet.com/]
               He is also core develoepr of Crash @[http://www.crashub.org/]
   
Julien Ponge:@[https://julien.ponge.org/]
               Author of VertX in Action
Many others :@[https://github.com/eclipse-vertx/vert.x/graphs/contributors]
Summary
REF:
- Vert.X guide for java devs @[https://github.com/vert-x3/vertx-guide-for-java-devs]
- VertX maven starter        @[https://github.com/vert-x3/vertx-maven-starter]
- Examples for amqp-bridge,  @[https://github.com/vert-x3/vertx-examples]
  grpc, core, docker, 
  gradle*/maven*, ignite, jca, 
  jdbc.  kafka, kotlin, mail, 
  metrics, mqtt, openshift3, 
  reactjs-server-side-rendering,
   redis, resteasy, rx, 
  service-discovery, 
  service-proxy, shell, spring, 
  sync, unit, web/web-client ...
- Webºserver examplesº       @[https://github.com/vert-x3/vertx-examples/tree/master/web-examples/src/main/java/io/vertx/example/web]
  angular*, auth, authjdbc, 
  authorisation, 
  blockinghandler, chat, 
  cookie, cors, 
  custom_authorisation, form, 
  helloworld, http2, , jwt, 
  mongo, react, realtime, rest, 
  sessions, staticsite, 
  templating, upload, vertxbus
- Web/ºJDBCºserver examples @[https://github.com/vert-x3/vertx-examples/blob/master/web-examples/src/main/java/io/vertx/example/web/jdbc/Server.java]

verticle
REF: @[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/intro/README.adoc]
-ºreusable unitº of Bºdeploymentº
                      ^^^^^^^^^^
                  - Can be passed some Gºconfigurationº like
                    credentials, network address,...
                  - can be deployed several times
                  - A verticle can deploy other verticles.

Oºverticleº1 ←────→ event─loop 1 ←──────→   1 Thread
  ^                 ^^^^^                     ^^^^^^
  │                 "input" event like        Must not handle I/O thread-blocking
  │                 network buffers,          or CPU intensive operations
  │                 timing events,            'executeBlocking' can be used
  │                 verticles messages, ...   to offload the blocking I/O operations
  │                                           from the event loop to a worker thread
  │
˂˂io.vertx.core.AbstractVerticle˃˃ Base Class
@[https://vertx.io/docs/apidocs/io/vertx/core/AbstractVerticle.html]
-Oº.start()º ← life-cycle sync/async method to be overrided
-Oº.stop ()º ← life-cycle sync/async method to be overrided
-Oº.vertxº   ← - Points to the BºVert.x environment where the verticle is deployedº
   ^^^^^^    · - provides methods to create HTTP/TCP/UDP/... servers/clients. 
             ·   Ex:
             ·   │ io.vertx.core.http.HttpServer server  = thisOº.vertxº.createHttpServer();
             · - provides access to the event bus.  
             ·   Ex:
             ·    ºSENDINGºVERTICLE:                        │ºRECEIVINGºVERTICLE:
             ·   ┌──────────────────────────────────────────┼────────────────────────────────────────
             ·   │ ...                                      │ ...
             ·   │Oºvertxº.eventBus()                       │ public void onMessage(
             ·   │   .request(wikiDbQueue,                  │          Message message)
             ·   │       jsonObject, options ,              │ {
             ·   │                   ^^^^^^^                │   String action = message.
             ·   │                   headers                │                headers().get("action");
             ·   │                  +payload codecs         │ 
             ·   │                  +tiemouts               │   switch (action) {
             ·   │       ^^^^^^^^^^  ^^^^^^^                │     case "action1":
             ·   │// Ussually jsonObject contains the data  │       ...
             ·   │// and an "action" header the action to   │       message.reply(
             ·   │// be executed by the receiving verticle  │           new JsonObject()
             ·   │       reply -˃ {                         │           .put("key1", value1));
             ·   │     if (reply.succeeded()) {             │       break;
             ·   │       ...                                │     case ...:
             ·   │     } else {                             │       ...
             ·   │       ...                                │     default:
             ·   │     }                                    │       message.fail(
             ·   │   });                                    │         ErrorCodes.BAD_ACTION.ordinal(),  
             ·   │                                          │         "Bad action: " + action);  
             ·   │                                          │   }
             ·   │                                          │ }
             
-Oº.config()º← - accessors to some deployment configuration to allow passing G*external configuration*
                 Ex:
                 │ public static final String CONFIG_WIKIDB_QUEUE = "wikidb.queue";
                 │ ...
                 │ wikiDbQueue =Oºconfig()º.getString(CONFIG_WIKIDB_QUEUE, "wikidb.queue");
                 │                             ^^^^^^                      ^^^^^^^^^^^^^^
                                       or Integers, booleans               Default param 
                                       complex JSON data, ...              if first is null

import io.vertx.core.AbstractVerticle;
public class MainVerticle extends AbstractVerticle {

  @Override
  public void start(Future˂Void˃ startFuture) {
                    ^^^^^^^^^^^^^^^^^^^^^^^^
                    No params for the sync version
    startFuture.complete();
  }
}

Event Bus
- main tool for communication between verticles using *messages*
  and one of:
  - point-to-point messaging
  - request-response messaging
  - publish / subscribe for broadcasting messages

   verticle 01                                      verticle 02
  (HTTP server)             event─bus              (DDBB client)
   │                          ║ ║                        │
   ├─── user 1234 ? ─────────→║ ║                        │
   │                          ║ ║─────── user 1234 ? ──→ │
   │                          ║ ║                        ├── ....─→
   │                          ║ ║                        │←─ ....
   │                          ║ ║←────── user 1234 ? ────┤
   │←── user 1234   ──────────║ ║                        │
        ^^^^^^^^^             ║ ║
  Message are free-form
  strings. (JSON recomended    ^
  for multi─language support   │
                               │

                  - It can be accessed through (simple)
                    TCP protocol for 3rd party apps
                    or exposed over general-purpose
                    messaging bridges (AMQP, Stomp,...)
                  - Support cluster support sending
                    messages to verticles deployed⅋running
                    in different application nodes
                  - a O*SockJS* bridge allows web applications
                    to seamlessly communicate over the event bus
                    from JavaScript running in the browser by
                    receiving and publishing messages just like
                    any verticle would do.

threading conf

By default Vert.x attaches CPU-core-thread 1˂--˃2 event loops
VertX Threading Strategies:
   Incoming network data -˃ accepting thread"N":
   accepting thread "N" -˃ event-loop thread: +event with data

When a verticle opens a network server and is deployed more than once,
then the events are being distributed to the verticle instances in a
round-robin fashion which is very useful for maximizing CPU usage with
lots of concurrent networked requests.
Testing
@[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-4/README.adoc]

@[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-4/src/test/java/io/vertx/guides/wiki/http/SampleHttpServerTest.java]

@RunWith(VertxUnitRunner.class)  ← annotation to JUnit tests to allow vertx-unit features
public class SampleHttpServerTest {

  private B*Vertx vertx*;

  @Before public void prepare() { B*vertx*= Vertx.vertx(); }

  @After public void finish(TestContext O*context*) {
    vertx.close(O*context*.asyncAssertSuccess());
  }

  @Test
  public void start_http_server
         (TestContext O*context*) {
                        ^^^^^^^
              // provided by the runner
              // provides access to basic assertions,
              // a context to store data,
              // and several async-oriented helpers

    Async Q*async* = O*context*.async();

    vertx
      .createHttpServer().requestHandler(
         req -˃ req.response().putHeader("Content-Type", "text/plain").end("Ok")
      )
      .listen(
        8080,
      O*context*.asyncAssertSuccess(
        server -˃ {
          WebClient webClient = WebClient.create(vertx);
          webClient.get(8080, "localhost", "/").send(ar -˃ {
            if (ar.succeeded()) {
              HttpResponse˂Buffer˃ response = ar.result();
            O*context*.assertTrue(response.headers().contains("Content-Type"));
            O*context*.assertEquals("text/plain", response.getHeader("Content-Type"));
            O*context*.assertEquals("Ok", response.body().toString());
            Q*async*.complete();
            } else {
            Q*async*.resolve(Promise.failedPromise(ar.cause()));
            }
          });
        }));
  }
}

*Ex 2:*
   check/test that a timer task has been called once,
   and that a periodic task has been called 3 times.
@[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-4/src/test/java/io/vertx/guides/wiki/database/WikiDatabaseVerticleTest.java]


RunWith(VertxUnitRunner.class)
public class WikiDatabaseVerticleTest {
  private Vertx vertx;
  @Before public void prepare(TestContext context) { vertx = ...       }
  @After  public void finish(TestContext context)  { vertx.close(...); }

  @Test /*(B*timeout=5000*)*/
  public void async_behavior(TestContext context) { // <1>
    Vertx vertx = Vertx.vertx();
    Async a1 = context.async();
    Async a2 = context.async(3); // ← works as a countdown that
                                      completes successfully after 3 calls.
    vertx.setTimer(100, n -> a1.complete());
    vertx.setPeriodic(100, n -> a2.countDown());
  }

  @Test
  public void crud_operations(TestContext context) {
    Async async = context.async();

    service.createPage(..., ...,
      context.asyncAssertSuccess(v1 -> {
        service.fetchPage(...,
          context.asyncAssertSuccess(json1 -> {
            context.assertTrue(json1.getBoolean("found"));
            context.assert...;
            ...
            async.complete();  // <1>
          }));
      }));
    async.awaitSuccess(B*5000*);
  }
}

HTTPS AAA
@[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-7/README.adoc]
Maven Bootstrap
@[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-1/README.adoc]
@[https://github.com/vert-x3/vertx-guide-for-java-devs/tree/3.8/step-1]
A minimally viable wiki written with Vert.x

Features:
- server-side rendering
- data persistence through a JDBC connection
  and async ddbb access

- Dependencies:
  - Vert.x web: "elegant" APIs to deal with routing, request payloads, etc.
  - Vert.x JDBC client: asynchronous API over JDBC.
  - other libreries for HTML/md rendering


$ git clone https://github.com/vert-x3/vertx-maven-starter project01
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            configured pom.xml +sample verticle + unit test + redeploy.sh
            ^^^^^^^^^^^^^^^^^^                                ^^^^^^^^^^^
      - Maven Shade Plugin configured to create a single      auto compile+redeploy
        "fat" Jar archive with all required dependencies      on code changes.
      - Exec Maven Plugin to provide the exec:java goal       (VERTICLE script var
        that in turns starts the application through the       must be adjusted to
        Vert.x io.vertx.core.Launcher class.                   match main verticle)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        (equivalent to running using the vertx cli tool)

$ cd project01
$ mvn package exec:java   # ← check that maven install is correct


Tip: The SQL database modules supported by the Vert.x project do not currently
   offer anything beyond passing SQL queries (e.g., an object-relational mapper)
   as they focus on providing asynchronous access to databases.
   However, nothing forbids using more advanced modules from the community,
   and we especially recommend checking out projects like this jOOq generator
   for VertX
   @[https://github.com/jklingsporn/vertx-jooq]

$ mvn clean package
$ java -jar target/project01-SNAPSHOT-fat.jar
Create HttpServer
REF:@[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-1/src/main/java/io/vertx/guides/wiki/MainVerticle.java]

    Promise˂Void˃ promise = Promise.promise();
    io.vertx.core.http.HttpServer server = vertx.createHttpServer();
                                           ^^^^^
                        Defined in io.vertx.core.AbstractVerticle Base Class

    io.vertx.ext.web.Router router = Router.router(vertx);
    router.get   ("/wiki/:page").handler(this::pageRenderingHandler);
                  ^^^^^^^^^^^^^                ^^^^^^^^^^^^^^^^^^^^
                  a match like /wiki/Hello     function signature
                  will make the page param     vvvvvvvvvvvvvvvvvvvv
                  available in the context →   void functionName(RoutingContext context)
    router.get   ...

    router.post().handler(io.vertx.ext.web.handler.BodyHandler.create())
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                          automatically decodes the body from the HTTP post requests
                          (form submissions,...), which can then be manipulated as Vert.x buffer objects.
    router.post  ("/delete"    ).handler(this::pageDeletionHandler);
    router.post  ...
    ...
           ^^^^    ^^^^^^^^^^^^
           HTTP    URL (optional)
           method

    server.requestHandler(router).listen(
       8080, /* Different deployments can share the port. Vertx will round-robin */
       /* AsyncResult */ar -˃ { //
        if (ar.succeeded()) {
          LOGGER.info("HTTP server running on port 8080");
          promise.complete();
        } else {
          LOGGER.error("Could not start a HTTP server", ar.cause());
          promise.fail(ar.cause());
        }
      });

    return promise.future();
  }

Reusable Verticles
@[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-2/README.adoc]

- resulting verticles will not have direct references
  to each other as they will only agree on destination names
  in the event bus as well as message formats.
- messages sent on the event bus will be encoded in JSON.

Ex:
@[https://github.com/vert-x3/vertx-guide-for-java-devs/tree/3.8/step-2/src/main/java/io/vertx/guides/wiki]
 HttpServerVerticle.java
 WikiDatabaseVerticle.java
 MainVerticle.java      ← its sole purpose is to bootstrap the app
                          and deploy other verticles.
 @[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-2/src/main/java/io/vertx/guides/wiki/MainVerticle.java]
  package io.vertx.guides.wiki;

  public class MainVerticle extends AbstractVerticle {
    @Override
    public void start(Promise promise) {
      Promise promise01 = Promise.promise();
      vertx.deployVerticle(new WikiDatabaseVerticle(), promise01);
      promise01.future().compose(id -> {
        Promise promise02 = Promise.promise();
        vertx.deployVerticle(
          "io.vertx.guides.wiki.HttpServerVerticle",  // <4>
          new DeploymentOptions().setInstances(2),    // <5>
          promise02);
        return promise02.future();
      }).setHandler(ar -> {
        if (ar.succeeded()) {
          promise.complete();
        } else {
          promise.fail(ar.cause());
        }
      });
    }
  }
RxJava Integration
@[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-7/README.adoc]
  
Client-Side
SockJS
@[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-10/README.adoc]
- SockJS:
  - Event-bus bridge allowing web apps to seamlessly communicate over
  - event bus from JavaScript running in the browser by receiving and publishing
  - messsages just like any verticle would do
Angular Client
@[https://github.com/vert-x3/vertx-guide-for-java-devs/blob/3.8/step-9/README.adoc]
QA
Cost of software failures
$312 billion per year: global cost of software bug (2013)
$300 billion dealing with the Y2K problem

$440 million loss by Knight Capital group Inc. in 30 minutes, August 2012
$650 million loss by NASA Mars missions in 1999; unit conversion bug
$500 million Arian 5 maiden flight in 1996; 64-bit to 16-bit conversion bug
"$Nightmare" billion Boeing 737Max

2011: Software caused 25% of all medical device recalls.
Checker framework
Java 8+
ºfix errors at compile timeº (vs later on at execution/runtime)
@[https://github.com/typetools/checker-framework]
@[https://checkerframework.org/manual/]
@[https://www.youtube.com/watch?v=6E1CSydgzQc]
@[https://www.baeldung.com/checker-framework]

º COMPARED TO ALTERNATIVES (FindBugs, Infer  Jlint, PMD,...)º
                 ┌─────────────┬────────┬────────┐                 ┌──────────────────┬─────────────────────┐
                 │ Null Pointer│        │        │                 │ Verification     │ Bug─Finding         │
                 │    errors   │ False  │Annotat.│                 │ (ºChecker FWº,)  │ (Infer,FindBugs,    │
                 │             │        │        │                 │                  │  SonarQube,...      │
                 │Found│ Missed│warnings│written │  ┌──────────────┼──────────────────┼─────────────────────┤
  ┌──────────────┼─────┼───────┼────────┼────────┤  │Goal          │ prove that       │ find some bugs      │
  │ºChecker FW.º │9    │ 9     │  4     │  35    │  │              │ no bug exits     │ at "low cost"       │
  ├──────────────┼─────┼───────┼────────┼────────┤  ├──────────────┼──────────────────┼─────────────────────┤
  │FindBugs      │0    │ 9     │  1     │  0     │  │Check specifis│ user provided    │ infer likely specs  │
  ├──────────────┼─────┼───────┼────────┼────────┤  │specificat    │                  │                     │
  │Jlint         │0    │ 9     │  8     │  0     │  ├──────────────┼──────────────────┼─────────────────────┤
  ├──────────────┼─────┼───────┼────────┼────────┤  │False         │ None!!!          │ acceptable          │
  │PMD           │0    │ 9     │  0     │  0     │  │negatives     │                  │                     │
  ├──────────────┼─────┼───────┼────────┼────────┤  ├──────────────┼──────────────────┼─────────────────────┤
  │Eclipse 2017  │0    │ 9     │  8     │  0     │  │False         │ manually supress │ heuristics focus on │
  ├──────────────┼─────┼───────┼────────┼────────┤  │positives     │ warnings         │ most important bugs │
  │IntelliJ      │0    │ 9     │  1     │  0     │  ├──────────────┼──────────────────┼─────────────────────┤
  │+@NotNull 2017│3    │ 6     │  1     │ 925+8  │  │Downside      │ user burden      │ missed bugs         │
  └──────────────┴─────┴───────┴────────┴────────┘  └──────────────┴──────────────────┴─────────────────────┘

RºPROBLEM:º                                          │BºSOLUTION:º
   STANDARD JAVA TYPE SYSTEM IS NOT GOOD ENOUGH      │  Java 8+ allows to compile programs
   - Next example compile, but fail at runtime:      │  using Oº"PLUGGABLE TYPE SYSTEMs"º,
     Ex.1:                                           │  allowing to apply stricter checks
       System.console().readLine(); ←RºNullPointerº  │  than default ones in compiler like
     Ex.2:                                           │  Ex:
       Collections.emptyList()                       │  $ javac º-processor NullnessCheckerº MyFile.java
               .add("one"); ←RºUnsupported Operationº│
     Ex.3:                                           │   PLUGABLE TYPE SYSTEM COMPILATION SCHEMA:
       Date key1 = new Date();                       │           (1)           No errors (2)
       myMap.put(key1, "now");                       │    Source ───→ Compiler ────┬───→ Executable
       myMap.get(key1);    ←  returns "now"          │      ^            │         │(2)       ^
       key1.setSeconds(0); ←RºMutate keyº            │      │            v         v          │
       myMap.get(key1);    ←Rºreturns nullº          │      │         Standard  OºOptionalº   │ Guaranteed
                                                     │      │         Compiler  OºType    º───┘ Behaviour
                                                     │      │         Errors    OºChecker º
                                                     │      │                      │
                                                     │      │                      v
                                                     │      └────────────────── Warnings :
                                                     │
                                                     │     (2) plugable type system allows generation
                                                     │         of executable to allow CI continue the
                                                     │         pipeline with further tests (functional
                                                     │         testing, configuration testing, ...)

º ___ _   _ ____ _____  _    _     _        _  _____ ___ ___  _   _ º
º|_ _| \ | / ___|_   _|/ \  | |   | |      / \|_   _|_ _/ _ \| \ | |º
º | ||  \| \___ \ | | / _ \ | |   | |     / _ \ | |  | | | | |  \| |º
º | || |\  |___) || |/ ___ \| |___| |___ / ___ \| |  | | |_| | |\  |º
º|___|_| \_|____/ |_/_/   \_\_____|_____/_/   \_\_| |___\___/|_| \_|º

(See new releases/versions at
  @[https://search.maven.org/search?q=g:org.checkerframework])

 ºSTEP 01:º                           │ ºSTEP 02:º
──────────────────────────────────────┼────────────────────────────────────────────────────
  Add next pom.xml dependencies like: │  tweak ºmaven-compiler-pluginº to use
  ˂dependency˃                        │  Checker Framework as a pluggable Type System:
      ˂groupId˃                       │  ˂plugin˃
        org.checkerframework          │    ˂artifactId˃ºmaven-compiler-pluginº˂/artifactId˃
      ˂/groupId˃                      │    ˂version˃3.6.1˂/version˃
      ˂artifactId˃                    │    ˂configuration˃
        checker-qual                  │      ˂source˃1.8˂/source˃
      ˂/artifactId˃                   │      ˂target˃1.8˂/target˃
      ˂version˃2.11.0˂/version˃       │      ˂compilerArguments˃
  ˂/dependency˃                       │        ˂Xmaxerrs˃10000˂/Xmaxerrs˃
  ˂dependency˃                        │        ˂Xmaxwarns˃10000˂/Xmaxwarns˃
      ˂groupId˃                       │      ˂/compilerArguments˃
        org.checkerframework          │     º˂annotationProcessors˃º ← "==" javac -processor ...
      ˂/groupId˃                      │        ˂annotationProcessor˃
      ˂artifactId˃                    │      org.checkerframework.checker.nullness.NullnessChecker
        checker˂                      │         ˂/annotationProcessor˃
      /artifactId˃                    │         ˂annotationProcessor˃
      ˂version˃2.11.0˂/version˃       │      org.checkerframework.checker.interning.InterningChecker
  ˂/dependency˃                       │         ˂/annotationProcessor˃
  ˂dependency˃                        │         ˂annotationProcessor˃
      ˂groupId˃                       │      org.checkerframework.checker.fenum.FenumChecker
        org.checkerframework          │         ˂/annotationProcessor˃
      ˂/groupId˃                      │         ˂annotationProcessor˃
      ˂artifactId˃                    │      org.checkerframework.checker.formatter.FormatterChecker
        jdk8                          │         ˂/annotationProcessor˃
      ˂/artifactId˃                   │     º˂/annotationProcessors˃º
      ˂version˃2.11.0˂/version˃       │      ˂compilerArgs˃
  ˂/dependency˃                       │        ˂arg˃-AprintErrorStack˂/arg˃
                                      │        ˂arg˃-Awarns˂/arg˃
                                      │      ˂/compilerArgs˃
                                      │    ˂/configuration˃
                                      │  ˂/plugin˃
 
(ºSTEP 03:º Manually add extended type annotations to your java code)

º _   _ ____ ____    _    ____ _____ º
º| | | / ___/ ___|  / \  / ___| ____|º
º| | | \___ \___ \ / _ \| |  _|  _|  º
º| |_| |___) |__) / ___ \ |_| | |___ º
º \___/|____/____/_/   \_\____|_____|º

- BºAvoiding Nullsº

 ºCHECKS  ON TYPESº                              │ºCHECKS ON FUNCTION DECLARATIONº
                                                 │                   ┌────┬────┬───────────────────────────┐
                                                 │                   │FUNC│FUNC│DESCRIPTION                │
  private static int func1                       │                   │PRE─│POST│                           │
    (º@NonNullº String[] args)                   │                   │COND│COND│                           │
  {                                              │ ┌─────────────────┼────┼────┼───────────────────────────┤
      return args.length;                        │ │@RequiresNonNull │X   │    │variables areºexpectedº to │
  }                                              │ │                 │    │    │be non─null when invoked.  │
                                                 │ ├─────────────────┼────┼────┼───────────────────────────┤
  public static void main                        │ │@EnsuresNonNull  │    │X   │variables areºguaranteedºto│
    (º@Nullableº String[] args) {                │ │                 │    │    │be non─null on return.     │
      ...                                        │ ├─────────────────┼────┼────┼───────────────────────────┤
      func1(args);                               │ │@EnsuresNonNullIf│    │X   │variables areºguaranteedºto│
  }         ^^^^                                 │ │                 │    │    │benon─null on ret.true/fals│
      [WARNING] ... [argument.type.incompatible] │ └─────────────────┴────┴────┴───────────────────────────┘
       incompatible types in argument.           │
       ºfound    : nullº                         │
       ºrequiredº: @Initializedº@NonNullº...     │

- BºConvert String constants into Safe Enum with Fenumº
                                                (Fake enum)
  static final @Fenum("country") String ITALY = "IT";
  static final @Fenum("country") String US = "US";
  ...
  static final @Fenum("planet") String MARS = "Mars";
  static final @Fenum("planet") String EARTH = "Earth";
  ...

  void function1(@Fenum("planet") String inputPlanet){
      System.out.println("Hello " + planet);
  }

  public static void main(String[] args) {
      obj.greetPlanets(US);   ←----  [WARNING] ...
  }                                   incompatible types in argument.
                                       found   : @Fenum("country") String
                                       required: @Fenum("planet") String

- BºRegular Expressionsº
  @Regex(1) private static String FIND_NUMBERS = "\\d*";
  ^^^^^^^^^                                      ^^^^^^
  Force String variable                       [WARNING] ...
  to store a regex with                       incompatible types in assignment.
  at least one matching                         found   : @Regex String
  group                                         required: @Regex(1) String



- BºValidating tainted (non-trusted) inputº

  º@Untaintedº
   String validate (String sqlInput) {
      // Do any suitable checks, throw on error
      @SuppressWarnings("tainting")      ← "swear" that developer got sure
      @Untainted String result = ...;       of input correctness
      return result;
  }

  void execSQL(º@Untaintedº String sqlInput) {
      ...
  }

  public static void main(String[] args) {
      obj.execSQL(arg[0]);             ← warning at compile time
      obj.execSQL(validate(arg[0]));   ← "OK". validate un-tain the input
  }

- BºMark as Immutableº
 º@ImmutableºDate date = new Date();
  date.setSeconds(0);   ← Rºcompile-time errorº


-ºAvoiding (certain) concurrency errorsº

  Lock Checker enforces a locking discipline:
  "which locks must be held when a given operation occurs"

  CHECKS ON TYPES                             │ CHECKS ON FUNCTION DECLARATION
                                              │                 ┌────┬────┬───────────────────────────┐
  º@GuardedBy("lockexpr1","lockexpr2",...)º   │                 │FUNC│FUNC│DESCRIPTION                │
             int var1 = ....;                 │                 │PRE─│POST│                           │
   ^^^^^^^^^^                                 │                 │COND│COND│                           │
  a thread may dereference the value referred │┌────────────────┼────┼────┼───────────────────────────┤
  to by var1 only when the thread holds all   ││@Holding        │X   │    │All the given lock exprs   │
  the locks that ["lockexpr1",...] currently  ││(String[] locks)│    │    │are held at method call    │
  evaluates to.                               │├────────────────┼────┼────┼───────────────────────────┤
                                              ││@EnsuresLockHeld│    │X   │Ensures locks are locked on│
                                              ││(String[] locks)│    │    │return,ex. lock adquired by│
                                              ││                │    │    │ReentrantLock.lock().      │
                                              │├────────────────┼────┼────┼───────────────────────────┤
                                              ││@EnsuresLockHeld│    │X   │Ensures locks are locked on│
                                              ││(String[] locks)│    │    │return,ex.lock conditionaly│
                                              ││                │    │    │adquired by ReentrantLock  │
                                              ││                │    │    │.lock()                    │
                                              ││                │    │    │if method return true|false│
                                              │└────────────────┴────┴────┴───────────────────────────┘
  ºSIDE EFFECT SPECIFICATIONSº
  ┌────────────────────┬───────────────────────────────────────────────┐
  │º@LockingFreeº      │method does NOT acquire│release locks:         │
  │                    │· it is not synchronized,                      │
  │                    │· it contains NO synchronized blocks           │
  │                    │· it contains no calls to lock│unlock methods  │
  │                    │· it contains no calls to methods that are not │
  │                    │  themselves @LockingFree                      │
  │                    │(@SideEffectFree implies @LockingFree)         │
  ├────────────────────┼───────────────────────────────────────────────┤
  │º@ReleasesNoLocksº  │· method maintains a strictly                  │
  │                    │  nondecreasing lock hold count                │
  │                    │  on the current thread for any locks          │
  │                    │  held at method call.                         │
  ├────────────────────┼───────────────────────────────────────────────┤
  │º@EnsuresLockHeldº  │method adquires new locsk                      │
  │º@EnsuresLockHeldIfº│(default if no @LockingFree│@MayReleaseLocks│  │
  │                    │@SideEffectFree│@Pure used).                   │
  └────────────────────┴───────────────────────────────────────────────┘


-BºFormat String Checkerº
  - prevents use of incorrect format strings in System.out.printf,....

    void printFloatAndInt
         (º@Format({FLOAT, INT})º String Oºformatº) 
    {
      System.out.printf(Oºformatº, 3.1415, 42);
    }
-ºI18n Format Checker examplesº
  MessageFormat.format("{0} {1}", 3.1415);
                                        ^  
                              second argument missing
  MessageFormat.format("{0, time}", "my string"); 
                                    ^^^^^^^^^^^
                                    cannot be formatted
                                    as Time type.
  MessageFormat.format("{0, thyme}", new Date()); 
                            ^^^^^
                            unknown format type

  MessageFormat.format("{0, number, #.#.#}", 3.1415);
                                    ^^^^^
                              subformat is invalid.

-ºProperty File Checker!!!!º RºTODOº
  -ºIt ensures that used keys are found in the corresponding º
   ºproperty file or resource bundle.º

-ºGUI Effect Checkerº 
  - It is difficult for a programmer to remember
    which methods may be called on which thread(s).
    (Main GUI thread or others)
   Checker types the method as if:
   - It accesses no UI elements (and may run on any thread); 
   - It may access UI elements  (and must run on the UI thread)

-º(physical) Internation System UNIT annotationsº:
  @Acceleration: Meter Per Second Square @mPERs2
  @Angle       : Radians @radians
                 Degrees @degrees
  @Area        : square millimeters @mm2,
                 square meters @m2
                 square kilometers @km2
  @Current     : Ampere @A
  @Length      : Meters @m 
                 millimeters @mm 
                 kilometers @km
  @Luminance   : Candela @cd
  @Mass        : kilograms @kg
                     grams @g
  @Speed       : meters per second   @m
                 kilometers per hour @kmPERh
  @Substance   : Mole @mol
  @Temperature : Kelvin @K
                 Celsius @C
  @Time        : seconds @s
                 minutes @min
                 hours @h

-º@Unsigned/@Signedº← guarantees values are not mixed

-ºtype alias or typedefº 
  share same representation as another type
  but is conceptually distinct from it.
  Ex 1: get sure that Strings representing addresses 
        and passwords are NOT mixed
  Ex 2: get sure that integers used for meters are 
        not mixed with integers used for centimeters.

  Example:
  @NonNull List˂String˃
  List˂@NonNull String˃
  @Regex String validation = "(Java|JDK) [7,8]"

  private String getInput(String parameterName){
   final String retval = @Tainted request.getParameter(parameterName);
   return retval;
  }

  private void runCommand(@Untainted String… commands){
   // the previously tainted String must be validated before being passed in here.
   ProcessBuilder processBuilder = new ProcessBuilder(command);
   Process process = processBuilder.start();
  }


SPARTA (anti-malware)
- Aimed at preventing malware from appearing in an app store.
- provides an information-flow type-checker customized to Android
  but can also be applied to other domains.
@[https://checkerframework.org/sparta/]
  The paper "Collaborative verification of information flow for a
  high-assurance app store" appeared in CCS 2014.
JavaDoc
-----------------------+-------------------------------------+-------------------------+-------   Example
Tag⅋ Parameter         | Usage                               | Applies to              | Since    /**
-----------------------+-------------------------------------+-------------------------+-------    * Short one line description.
@authorJohn Smith      | Describes an author.                | Class, Interface, Enum  |           * 

-----------------------+-------------------------------------+-------------------------+------- * Longer description. ... @versionversion | Provides software version entry. | Class, Interface, Enum | * ...here. | Max one per Class or Interface. | | *

-----------------------+-------------------------------------+-------------------------+------- * And even more explanations to follow @sincesince-text | Describes when this functionality | Class, Interface, Enum, | * in consecutive paragraphs | has first existed. | Field, Method | * -----------------------+-------------------------------------+-------------------------+------- * @author John Bla @seereference | Provides a link to other element | Class, Interface, Enum, | * @param variable Description .... | of documentation. | Field, Method | * @return Description .... -----------------------+-------------------------------------+-------------------------+------- */ @paramname descrip | Describes a method parameter. | Method | public int methodName (...) { -----------------------+-------------------------------------+-------------------------+------- // method body with a return statement @return description | Describes the return value. | Method | } -----------------------+-------------------------------------+-------------------------+------- @exceptionclass desc | Describes an exception that may | Method | -----------------------+-------------------------------------+-------------------------+------- @throwsclass desc | be thrown from this method. | | -----------------------+-------------------------------------+-------------------------+------- @deprecated descr | Describes an outdated method. | Class, Interface, Enum, | | | Field, Method | -----------------------+-------------------------------------+-------------------------+------- {@inheritDoc} | Copies the description from the | Overriding Method | 1.4.0 | overridden method. | | -----------------------+-------------------------------------+-------------------------+------- {@linkreference} | Link to other symbol. | Class, Interface, Enum, | | | Field, Method | -----------------------+-------------------------------------+-------------------------+------- {@value#STATIC_FIELD} | Return the value of static field. | Static Field | 1.4.0 -----------------------+-------------------------------------+-------------------------+------- {@codeliteral} | Formats literal text in the code | Class, Interface, Enum, | 1.5.0 | font. It is equivalent to | Field, Method | | {@literal} | Class, Interface, Enum, | 1.5.0 -----------------------+-------------------------------------+-------------------------+------- {@literalliteral} | Denotes literal text. The enclosed | Field, Method | | text is interpreted as not | | | containing HTML markup or nested | | | javadoc tags. | | -----------------------+-------------------------------------+-------------------------+-------

SonarQube
- Note that reports from this tools are not 


Alternatives
- alternatives to SonarQube include:
  - Facebook Infer @[http://fbinfer.com/]
    (Static analysis Java/C/...)
  - Scrutinizer:
  - FindBugs: (Looks unmaintained in GitHub)
  - Eclipse Static Code Analasys:
    Eclipse → Properties → Java → Compiler → Errors/Warnings → Null analysis:
      Null pointer access
      Potential null pointer access
      Redundant null check:
        x Include 'assert' in null analysis
        x Enable annotation-based null analysis
          Violation of null specification
          Conflict between null annotations an null inference
          Unchecked conversion from non-annotated type to @NonNull type
          Problems detected by pessimistic analysis fro free type variables
          Unsafe "@Nonnull" interpretation of the free type variable from library
          Redundant null anotation:
          "@NonNull" parametere not annotated in overriding method
          Missing "@NonNullByDefault" annotation on package
          x Use default annotations for null specifications (configure)
          x Inherit null annotations
          x Enable syntatic null analisys for fields
      x Treat above errors like fatal compile erros (make compiled code not executable)
UUID: bdf38754-3114-4343-a768-e8d24027f91b
JDepend
@[https://github.com/clarkware/jdepend]
https://htmlpreview.github.io/?https://github.com/clarkware/jdepend/blob/master/docs/JDepend.html

 What Is It?
  -----------
  JDepend traverses Java class and source file directories and
  generatesºdesign-quality-metrics for each Java packageº
 ºin terms of its extensibility, reusability, and maintainabilityº
 ºto effectively manage and control package dependencies.º
Junit
@[https://www.infoq.com/news/2018/01/VSCodeJunit]
Exceptions
- (compiler) checked vs unchecked (Error, RuntimeException and their subclasses).
- Checked: All except Error, RuntimeException and their subclasses
- Error: Exceptional conditions external to the application.
java.lang.Object
   java.lang.Throwable
       java.lang.Exception
           java.lang.RuntimeException (non-checked)
           java.lang.*Exception       (checked -A)
       java.lang.Error                (non-checked)

- The Throwable class is the superclass of all errors and exceptions in the
  Java language.  Only objects that are instances of this class (or one of
  its subclasses) are thrown by the JVM or can be thrown by the Java throw
  statement. Similarly, only this class or one of its subclasses can be the
  argument type in a catch clause. For the purposes of compile-time checking
  of exceptions, Throwable and any subclass of Throwable that is not also a
  subclass of either RuntimeException or Error are regarded as checked
  exceptions.
- An Error is a subclass of Throwable that indicates serious problems that a
  reasonable application should not try to catch. Most such errors are
  abnormal conditions. The ThreadDeath error, though a "normal" condition, is
  also a subclass of Error because most applications should not try to catch it.
  

"Optional": Avoid Nulls
REF
import java.util.Optional;
Optional optional = Optional.ofNullable(a); // ← Create an optional
optional.map ( s -˃ "RebelLabs:" + s);               // ← Process the optional
optional.flatMap( s -˃ Optional.ofNullable(s));      // ← map a function that retunrs Optional
optional.ifPresent(System.out::println);             // ← run if the value is ther

optional.get();                                      // ← Alt 1: get the value or throw an exception
optional.orElse("Hello world!");                     // ← Alt 2: get the value or default

optional.filter( s -˃ s.startsWith("RebelLabs"));    // ← return empty Optional if not satisfied
JSR Annotations
 foRºDefect Detectionº
@[https://stackoverflow.com/questions/1476757/jsr305-vs-jsr308-java-type-anotations-which-is-going-to-be-the-standard]
Type Annotations
----
@NonNull              compiler can determine cases where a      │ @(Un)Tainted          Identity types of data that should
                      code path might receive a null value,     │                       not be used together, such as remote
                      without ever having to debug a            │                       user input being used in system
                      NullPointerException. The compiler        │                       commands, or sensitive information in
                      just print a warning, but it              │                       log streams
                      continues to compile!!!                   │
                                                                │ @m                    Units of measure ensures that numbers
@ReadOnly             compiler will flag any attempt to         │                       used for measuring objects are used
                      change the object. This is similar to     │                       and compared correctly, or have
                      Collections.unmodifiableList, but         │                       undergone the proper unit
                      more general and verified at compile time.│                       conversion.
                                                                │
@Regex                Provides compile-time verification        │ @FunctionalInterface  indicates that the type declaration
                      that a String intended to be used as      │                       is intended to be a functional
                      a regular expression is a properly        │                       interface, as defined by the Java
                      formatted regular expression.             │                       Language Spec.

ºExamplesº:
Annotation
@NonNull List                              ← A non-null list of Strings.
List<@NonNull String>                              ← A list of non-null Strings.
@Regex String validation = "(Java|JDK) [7,8]"      ← Check at compile time that this String is a valid regular expression.
private String getInput(String parameterName){     ← The object assigned to retval is tainted and not for use in sensitive operations.
    final String retval =
      @Tainted request.getParameter(parameterName);
  return retval;
}

private void runCommand(@Untainted String… commands){            Each command must be untainted. For example, the previously
  ProcessBuilder processBuilder = new ProcessBuilder(command);   tainted String must be validated before being passed in here.

  Process process = processBuilder.start();
}

Annotation 
processors JSR 269
(Data Binding,
Lombok, ...)
Dependency
injection JSR 330
Dagger,Spring,...
@[http://www.theserverside.com/feature/Spring-vs-Guice-The-Clash-of-the-IOC-Containers]
A: t's important to realize that Dagger was created after Guice, by one
of Guice's creators ("Crazy Bob" Lee) after his move to Square:
  - Spring was originally released in October 2002.
  - Google originally publicly released Guice in March 2007.
  - JSR-330 formalized javax.inject annotations in October 2009,
    with heavy input from Google (Bob Lee), Spring, and other industry
    players.
  - Square originally released Dagger 1 publicly in May 2013.
  - Google originally released Dagger 2 publicly in April 2015.
  - Square marked Dagger 1 as deprecated 10 days ago,
    on September 15, 2016.
Maven
PUBLIC REPOSITORY:      @[https://mvnrepository.com/]
Artifact Search Engine: @[http://search.maven.org/]

GOAL
- unit of work.
- A goal accepts configuration properties (parameters) to customize
  its run-time behavior
- Ex: Compiler:compile defines a set of parameters to specify target
  JDK version or switching on/off compiler optimizations
  - An ºordered listº of goals can be attached to a Bºlifecycle phaseº.
Ex:
                               Executes next goals in order
mvn Bºpackageº      | resources:resources →
    ^Lifecicle  | compiler:compile →
                | resources:testResources →
                | compiler:testCompile →
                | surefire:test jar:jar

SNAPSHOTS
Q: What exactly is a Maven Snapshot and why do we need it?
A: A snapshot version is one that has not been released (Oºfuture releaseº).
   The idea is that ºbeforeº a "1.0" release is done, there exists
   a 1.0Oº-SNAPSHOTº. That version is what might become 1.0. It's
   basically Oº"1.0 under development"º. This might be close to a real
   1.0 release, or pretty far (right after the 0.9 release, for ex.)

   The difference between a "real" version and a snapshot version is
   that ºsnapshots might get updatesº.  That means that downloading
   1.0-SNAPSHOT today might give a different file than downloading it
   yesterday or tomorrow.
   In contrast OºReleased versions are inmutablesº:
   updates to "1.0.0" requires new version "1.0.1".

   Snapshot dependencies should only exist during development.
  ºReleased versions (i.e. no non-snapshot) should NEVER have aº
  ºdependency on snapshotsº

˂repository˃
    ...
    ˂snapshots˃
        ˂enabled˃true˂/enabled˃
        ˂updatePolicy˃
          always|daily(default)|
          "X"minutes|never
        ˂/updatePolicy˃
    ˂/snapshots˃
˂/repository˃

Standard Lifecycles
ºCLEAN,DEFAULT,SITEº
| DEFAULT LIFECYCLE         | CLEAN LIFECYCLE | SITE LIFECYCLE
| process-resources         | TODO            | TODO
|  compile
|   process-classes
|    process-test-resources
|     test-compile
|      test
|       prepare-package
|        package
|         install

Compiling & Installing
  Command                           Description
$ mvn clean                         Remove the (current_working_directory/)target folder
$ mvn compile                       (goal list: clean→compile)
$ mvn clean package                 Compiles and generates the (JAR/WAR/...) package
$ mvn clean install                 (goal list: clean→compile→test→package→install_local )
                                    # : skip tests
$ mvn clean install \               (goal list: clean→compile→     package→install_local )
  -Dmaven.test.skip=true
$ mvn clean deploy                  Compile... and installs into remote ("corporate") server
                                    ( clean→compile→test→package→install_local→install_pub )
-----------------------------------------------------------
Common options:
 –U                   Force library (download) update
 –P myProfileX        Execute profile myProfileX
 –o                   offline mode. Search deps in local repo.
 -Dgenerate.pom=true  Generates the pom locally for an artefact when installing
                      and compiling. Very useful to make offilne mode work properly.
-----------------------------------------------------------
help:active-profiles   : List (project|user|global)
                        active profile for the build
help:effective-pom     : Displays effective POM for
                          current build
help:effective-settings: Prints calculated settings
help:describe groupId artifactId: Describes plugin attributes

mvn exec Main
@[https://stackoverflow.com/questions/9846046/run-main-class-of-maven-project]

$ mvn  -Dexec.args="arg0 ..." ºexec:javaº -Dexec.mainClass="com.example.Main"

pom.xml
ºReuse constants:º
${project.groupId}         ← Reuse project groupId in POM
${project.artifactId}      ← Reuse project artifactId in POM
${project.version}         ← Reuse project version in POM

º${my.property.name}º ← Reuse properties in POM


˂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/maven-v4_0_0.xsd"˃
  ˂modelVersion˃4.0.0˂/modelVersion˃
º˂!-- project coordinates { --˃º
  ˂groupId˃com.mycompany.mygroupid˂/groupId˃
  ˂artifactId˃myArtifactId˂/artifactId˃
º˂!-- packaging value := jar|war|ear|pom|maven-plugin|ejb|rar|par|aar|apklib|... --˃º
  ˂packaging˃jar˂/packaging˃
º˂!-- See @[https://semver.org/] (Semantic Versioning) for more info                     º
º  Version X.W.Z                                                                         º
º   X MAJOR  Must differ for non-compatible API changes,                                 º
º   W MINOR  W increase with new functionality backwards-compatible with X.(W-1) version º
º   Z PATCH  backwards-compatible bug fixes that does NOT add new functionality          º
--˃
  ˂version˃1.0-SNAPSHOT˂/version˃ º˂!-- Remember: SNAPSHOT refers to development/future release --˃º
º˂!-- } --˃º
  ˂name˃MyPackageDescriptiveName˂/name˃
  ˂url˃http://maven.apache.org˂/url˃
    ˂properties˃
        ˂maven.compiler.source˃1.8˂/maven.compiler.source˃
        ˂maven.compiler.target˃1.8˂/maven.compiler.target˃
    ˂/properties˃
  ˂dependencies˃

º˂!-- Typical dependencies for in-memory data-collection handling { --˃º
    ˂dependency˃
        ˂groupId˃com.google.guava˂/groupId˃
        ˂artifactId˃guava˂/artifactId˃
        ˂version˃21.0˂/version˃
    ˂/dependency˃
º˂!-- } --˃º

º˂!-- Typical dependencies for logging { --˃º
    ˂dependency˃
        ˂groupId˃ch.qos.logback˂/groupId˃
        ˂artifactId˃logback-classic˂/artifactId˃
        ˂exclusions˃
            ˂!-- Avoid problem:
            SLF4J: Class path contains multiple SLF4J bindings.
            SLF4J: Found binding in [jar:file:~/.m2/repository/org/slf4j/slf4j-jdk14/1.7.21/slf4j-jdk14-1.7.21.jar!/org/slf4j/impl/StaticLoggerBinder.class]
            SLF4J: Found binding in [jar:file:~/.m2/repository/ch/qos/logback/logback-classic/1.1.7/logback-classic-1.1.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
            --˃
            ˂exclusion˃
                ˂groupId˃org.slf4j˂/groupId˃
                ˂artifactId˃slf4j-jdk14˂/artifactId˃
            ˂/exclusion˃
        ˂/exclusions˃
        ˂version˃1.1.7˂/version˃
    ˂/dependency˃
º˂!-- } --˃º

º˂!-- Typical dependencies for JSON handling { --˃º
    ˂dependency˃
        ˂groupId˃com.fasterxml.jackson.core˂/groupId˃
        ˂artifactId˃jackson-core˂/artifactId˃
        ˂version˃2.8.8˂/version˃
    ˂/dependency˃

    ˂dependency˃
        ˂groupId˃com.fasterxml.jackson.core˂/groupId˃
        ˂artifactId˃jackson-databind˂/artifactId˃
        ˂version˃2.9.0.pr3˂/version˃
    ˂/dependency˃

    ˂dependency˃
        ˂groupId˃com.fasterxml.jackson.datatype˂/groupId˃
        ˂artifactId˃jackson-datatype-joda˂/artifactId˃
        ˂version˃2.8.8˂/version˃
    ˂/dependency˃

    ˂dependency˃
        ˂groupId˃org.web3j˂/groupId˃
        ˂artifactId˃core˂/artifactId˃
        ˂version˃3.2.0˂/version˃
    ˂/dependency˃
º˂!-- } --˃º

º˂!-- test dependencies (Not included in production system) { --˃º
    º˂!-- Unit test dependencies { --˃º
    ˂dependency˃
      ˂groupId˃junit˂/groupId˃
      ˂artifactId˃junit˂/artifactId˃
      ˂version˃3.8.1˂/version˃
      ˂scope˃test˂/scope˃
    ˂/dependency˃
    º˂!-- } --˃º

    º˂!--  REST API (Functional) test dependencies { --˃º
    ˂dependency˃
        ˂groupId˃io.rest-assured˂/groupId˃
        ˂artifactId˃scala-support˂/artifactId˃
        ˂version˃3.0.6˂/version˃
        ˂scope˃test˂/scope˃
    ˂/dependency˃
    ˂dependency˃
        ˂groupId˃io.rest-assured˂/groupId˃
        ˂artifactId˃json-schema-validator˂/artifactId˃
        ˂version˃3.0.6˂/version˃
        ˂scope˃test˂/scope˃
    ˂/dependency˃
    º˂!-- } --˃º
º˂ } --˃º


  ˂/dependencies˃
˂/project˃

Reactor(POM aggregate vs inherit) Maven supports both project inheritance (set a parent project) and aggregation (reactor mechanism). MVN reactor allows to execute a goal (build,...) over a set of projects. The reactor will determine the build order according to defined dependencies on each pom. MVN 2 improved reactor making it transparent to users. Anyway a plugin exists to customize the interaction with the reactor: maven-reactor-plugin If we launch compilation in a multi-module (like AbsisParentPom) and something goes wrong, we can always re-start from the last failed module with the '--resume-from' option like: $ mvn --resume-from=com.myCompany.myModule:MyArtifact clean install -P myProfile -DskipTests=true
Dependency Management
mvn dependency:analyze
list two things:
Dependencies used but not declared.
 If found in the parent pom, there is no
 problem when compiling, but must be
 included at runtime on the server.

Dependencies declared but not used for
the scope provided (compile, provided…).
They can be in the parent pom too.
Noneless, can be needed at runtime.

mvn dependency:tree
Ex. Ussage:
  $ mvn dependency:tree -Dscope=compile
                         ^^^^^^^^^^^^^^
                         do not show test/provided/... dependencies
  → ...
  → [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ tamperproof ---
  → [INFO]ºcom.myCompany:myProject:jar:1.0-SNAPSHOTº
  → [INFO] +- org.web3j:core:jar:4.3.0:compile
  → [INFO] |  +- org.web3j:abi:jar:4.3.0:compile
  → [INFO] |  |  \- org.web3j:utils:jar:4.3.0:compile
  → [INFO] |  |     \- org.bouncycastle:bcprov-jdk15on:jar:1.60:compile
  → [INFO] |  +- org.web3j:crypto:jar:4.3.0:compile
  → [INFO] |  |  \- org.web3j:rlp:jar:4.3.0:compile
  → [INFO] |  +- org.web3j:tuples:jar:4.3.0:compile
  → [INFO] |  +- com.github.jnr:jnr-unixsocket:jar:0.21:compile
  → [INFO] |  |  +- com.github.jnr:jnr-ffi:jar:2.1.9:compile
  → [INFO] |  |  |  +- com.github.jnr:jffi:jar:1.2.17:compile
  → [INFO] |  |  |  +- org.ow2.asm:asm:jar:5.0.3:compile
  → [INFO] |  |  |  +- org.ow2.asm:asm-commons:jar:5.0.3:compile
  → [INFO] |  |  |  +- org.ow2.asm:asm-analysis:jar:5.0.3:compile
  → [INFO] |  |  |  +- org.ow2.asm:asm-tree:jar:5.0.3:compile
  → [INFO] |  |  |  +- org.ow2.asm:asm-util:jar:5.0.3:compile
  → [INFO] |  |  |  +- com.github.jnr:jnr-a64asm:jar:1.0.0:compile
  → [INFO] |  |  |  \- com.github.jnr:jnr-x86asm:jar:1.0.2:compile
  → [INFO] |  |  +- com.github.jnr:jnr-constants:jar:0.9.11:compile
  → [INFO] |  |  +- com.github.jnr:jnr-enxio:jar:0.19:compile
  → [INFO] |  |  \- com.github.jnr:jnr-posix:jar:3.0.47:compile
  → ...

Related:

- JDepend traverses Java class and source file directories and
  generatesºdesign-quality-metrics for each Java packageº
 ºin terms of its extensibility, reusability, and maintainabilityº
 ºto effectively manage and control package dependencies.º
[[bdf38754-3114-4343-a768-e8d24027f91b?]]
POM BEST PRACTICES:
- update pom dependency to latest version
   Ex. Update org.checkerframework.*:
   $ mvn versions:use-latest-versions -Dincludes="org.checkerframework:*"

REF: @[http://geertschuring.wordpress.com/2011/02/23/maven-best-practices/]
- Replace references like ${artifactId} or ${pom.artifactId} with new
 º${project.artifactId}ºsyntax. This syntax follows the XML document
  structure, making it easy to remember and predict the value that the
  reference will result in.

- Try to avoid using inherited properties. Developers can easily forget
  that a certain property is used by a child POM and change the value
  breaking the build in an unexpected place. Secondly, its quite annoying
  not to be able to easily lookup a property without having to find
  and examine the parent POM.

- Use the dependency management section of the parent pom to define
  all dependency versions, but do not set a scope here so that all
  dependencies have scope compile by default.

- Use properties to define the dependency versions. This way you can
  get an overview of all versions quickly.

- Use the pluginmanagement section of parent pom to define versions for
  ºallº plugins that your build uses, even standard maven plugins like
  maven-compile-plugin and maven-source-plugin. This way your build will
  not suddenly behave differently when a new version of a plugin is released.

- When using a parent POM not located in the directory directly above
  the current POM define an empty relativePath element in your parent section.

- Use the dependency plugin to check your project for both unnecessary
  dependencies and undeclared-but-used-none-the-less dependencies.
  The goal is called ‘analyze’, so run the following command on the
  console: “mvn dependency:analyze

- Make sure the pom files contain all the repository references needed
  to download all dependencies. If you want to use a local repository
  instead of downloadin strait from the internet then use the maven
  settings file to define mirrors for the individual repositories that
  are defined in the poms.

- If you use Nexus, then do not create repository groups containing both
  hosted and proxied repositories. This will dramaticly reduce the
  responsiveness because Nexus will check the remote locations of the
  proxied repositories even if a hosted repository contains the requested
  artifact.

IC Best Practices
REF
New skeleton:
mvn archetype:generate -DgroupId=my.groupId \
   -DartifactId=myArtifact \
   -DarchetypeArtifactId=maven-archetype-quickstart \
   -DinteractiveMode=false
Show ordered-by-phace list of goals executed:
(Very useful to skip slow/non-important goals like doc, style-checks,...)
$ mvn fr.jcgay.maven.plugins:buildplan-maven-plugin:list \
  -Dbuildplan.tasks=install
Quick local install 
(bypass tests/style-checks/...)
 $ mvn resources:resources \
       compiler:compile \
       jar:jar \
       install:install
Add non-standard src dir
- Useful when some tool auto-generates code outside the standard
  src/main/java diretory.
˂build˃
   ...
   ˂sourceDirectory˃
     src/main/generated_java
   ˂/sourceDirectory˃

   ˂testDirectory˃
     src/functionalTest/java
   ˂/testDirectory˃
˂/build˃
add local jar dependency
(vs. maven central repository):
˂dependency˃
  ˂groupId˃   ...˂/groupId˃
  ˂artifactId˃...˂/artifactId˃
  ˂version˃   ...˂/version˃
  ˂scope˃...˂/scope˃
  ˂systemPath˃/local/path/in/my/file/system/myjar.jar˂/systemPath˃
˂/dependency˃
set parent/child pom
- Allows to inherit project dependency in children projects

.../parent/pom.xml              | .../parent/child1/pom.xml

˂modelVersion˃4.0.0             | ˂parent˃
˂/modelVersion˃                 |   ˂groupId˃...˂/groupId˃
˂groupId˃....˂/groupId˃         |   ˂artifactId˃parent˂/artifactId˃
˂artifactId˃parent˂/artifactId˃ |   ˂version˃1˂/version˃
˂version˃0.1.0˂/version˃        |   ˂relativePath˃
˂packaging˃pom˂/packaging˃      |      ../pom.xml˂/relativePath˃
                                | ˂/parent˃
                                | ˂dependecies˃
˂modules˃                       |   ˂dependency˃
  ˂module˃./child1˂/module˃     |     ˂groupId˃...˂/groupId˃
  ˂module˃./child2˂/module˃     |     ˂artifactId˃...˂/artifactId˃
˂/modules˃                      |   ˂/dependency˃...
                                | ˂/dependecies˃
˂dependencyManagement˃          |
  ˂dependencies˃                |
  ˂dependency˃                  |
    ˂groupId˃...˂/groupId˃      |
    ˂artifactId˃...˂/artifactId˃| no need to repeat version/scope
    ˂version˃X.Y.Z˂/version˃    | in childs
    ˂scope˃compile˂/scope˃    ˂-| compile | provided
  ˂/dependency˃...              |
  ˂dependencies˃                |
˂/dependencyManagement˃

Install non-mavenized jar:
mvn install:install-file -Dfile=path_to_local_file -DgroupId=˂groupId˃ \
   -DartifactId=˂artifactId˃ -Dversion=˂version˃ -Dpackaging=˂packaging˃
Maven Central
Publish artifacts to MVN Central
@[http://maven.apache.org/repository/guide-central-repository-upload.html]

Requirements

NOTE: OºOnly releases allowedº (Not snapshots)
˂?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-v4_0_0.xsd"˃
  ˂modelVersion˃4.0.0˂/modelVersion˃

  ˂groupId˃com.u1.training˂/groupId˃
  ˂artifactId˃ossrh-demo˂/artifactId˃
  ˂version˃1.0˂/version˃
  ˂packaging˃jar˂/packaging˃

  ˂name˃${project.groupId}:${project.artifactId}˂/name˃
  ˂description˃demo deploy via OSSRH˂/description˃
  ˂url˃http://github.com/u1/ossrh-demo˂/url˃

  ˂licenses˃
    ˂license˃
      ˂name˃The Apache Software License, Version 2.0˂/name˃
      ˂url˃http://www.apache.org/licenses/LICENSE-2.0.txt˂/url˃
    ˂/license˃
  ˂/licenses˃

  ˂developers˃
    ˂developer˃
      ˂name˃Manfred Moser˂/name˃
      ˂email˃manfred@sonatype.com˂/email˃
      ˂organization˃Sonatype˂/organization˃
      ˂organizationUrl˃
        http://www.sonatype.com
      ˂/organizationUrl˃
    ˂/developer˃
  ˂/developers˃

  ˂scm˃
    ˂connection˃scm:git:git://github.com/u1/a.git˂/connection˃
    ˂developerConnection˃
      scm:git:ssh://github.com:u1/a.git
    ˂/developerConnection˃
    ˂url˃http://github.com/u1/a/tree/master˂/url˃
   ˂/scm˃

...

˂/project˃

- All projects except pom-packaging ones have to supply
  OºJAR files containing Javadoc and sourcesº
- Supply Javadoc and Sources:  The naming convention is like:
  artifactId"-"version"-"classifier"."packaging"
  Ex:
  my-artifact-id-1.4.7-sources.jar
  my-artifact-id-1.4.7-javadoc.jar

- All files need to be signed with GPG/PGP including the
  matching *.asc file. E.g.
  example-application-1.4.7.pom          → example-application-1.4.7.pom.asc
  example-application-1.4.7.jar          → example-application-1.4.7.jar.asc
  example-application-1.4.7-sources.jar  → example-application-1.4.7-sources.jar.asc
  example-application-1.4.7-javadoc.jar  → example-application-1.4.7-javadoc.jar.asc
- we discourage the usage of ˂repositories˃ and
  ˂pluginRepositories˃ and instead publish any required
  components to the Central Repository

PGP Signature
- Allow to validate artifact at download against a public key server
- PGP signatures is required for artifacts (all files except checksums),
  and matching public key uploaded to a server like
  http://pgp.mit.edu
- Build tool integration

Publish Best patterns
- Use approved repository hosting location:
  Apache Software Foundation (for all Apache projects)
  FuseSource Forge (focused on FUSE related projects)
  Nuiton.org

- User automatic publication in "forges" that provide hosting services

- OSS Repository Hosting
  - Approved repository provided by Sonatype for OSS Project that want to
    get their artifacts into Central Repository.
  - Open an account as explained at
    @[http://central.sonatype.org/pages/ossrh-guide.html]

Post-namespace registration
(e-mail received after Namespace correct registration)
[ Issue@Jira ]
Thad Watson resolved OSSRH-39644: Resolution: Fixed

Configuration has been prepared, now you can:
→ Deploy snapshot artifacts into repository
  https://oss.sonatype.org/content/repositories/snapshots

→ Deploy release artifacts into the staging repository
  https://oss.sonatype.org/service/local/staging/deploy/maven2
→ Promote staged artifacts into repository 'Releases'
→ Download snapshot and release artifacts from group
  https://oss.sonatype.org/content/groups/public

→ Download snapshot, release and staged artifacts from
  staging group
  https://oss.sonatype.org/content/groups/staging
 ºplease comment on this ticket when you promotedº
 ºyour first release, thanks                     º

Test settings
@[https://www.apache.org/dev/publishing-maven-artifacts.html#test-your-settings]
- Make sure there are ºno dependencies on snapshotsº in the POMs to be released.
  However, the project you want to stage must be a SNAPSHOT version
- Check that your POMs will not lose content when they are rewritten
  during the release process:
- Verify that all pom.xml files have an SCM definition
- Do a dryRun release: Oºmvn release:prepare -DdryRun=trueº
  Postcript: You may also wish to pass Oº-DautoVersionSubmodules=trueº
  as this will save you time if your project is multi-moduled.
- Diff the original file pom.xml with the one called pom.xml.tag to
  see if the license or any other info has been removed. This has been known
  to happen if the starting ˂project˃ tag is ºNOTº on a single
  line. The only things that should be different between these files are the
  ˂version˃ and ˂scm˃ elements. Any other changes you must
  backport yourself to the original pom.xml file and commit before
  proceeding with the release.

Deploy snapshot
@[https://www.apache.org/dev/publishing-maven-artifacts.html#publish-snapshot]
  mvn deploy
  ...
  [INFO] [deploy:deploy]
  [INFO] Retrieving previous build number from apache.snapshots.https
  ...

Prepare release
@[https://www.apache.org/dev/publishing-maven-artifacts.html#prepare-release]
mvn release:clean
mvn release:prepare # creates new tag in SVN, automatically checking in.

Stage release for a vote
@[https://www.apache.org/dev/publishing-maven-artifacts.html#stage-release-vote]
mvn release:perform
# release will be automatically inserted in a temp staging dir
Troubleshooting
@[https://www.apache.org/dev/publishing-maven-artifacts.html#troubleshooting]

pom utils
@[https://github.com/kdgregory/pomutil]

Utilities to clean, organize, and restructure Maven POMs.

- POM Cleaner
  "Cleans up" a single POM, normalizing plugin and dependency specifications, 
  converting hardcoded versions to properties, consitently ordering top-level 
  elements, and pretty-printing the output.
  There is also a version of this tool that runs as a web-app.

- Version Updater
  Updates the version for a set of POMs, either to a specified version or the 
  next sequential version.

- Dependency Check
  Examines a project to find dependencies that are specified but unused, and 
  those that are used but unspecified (ie, transitive dependencies that 
  should be direct).
Jib Image Builder
Docker+mvn/gradle
@[https://www.infoq.com/news/2018/08/jib]
@[https://github.com/GoogleContainerTools/jib]
- Build Java Container without Docker/Dockerfile
- Jib's build approach separates the Java application 
  into multiple layers, so when there are any code changes,
  only those changes are rebuilt, rather than the entire application.
  - these layers are layered on top of a distroless base image.
    containing only the developer's application and its runtime deps.
    
ºDocker build flow º

│Project│ →(build)→ │JAR│
                       │                                                                  │Container │
                       ├───────→   │Build Context│ →(build)→ │ Container Image │ →(push)→ │Image     │
                       │                                     │ (docker cache)  │          │(registry)│
              │Dockerfile│


ºJib Build Flow:º

                                                                                           │Container │
│Project│ ─────────────────────────────(Jib)──────────────────────────────────────────────→│Image     │
                                                                                           │(registry)│
Gradle
Wrapper
@[https://docs.gradle.org/current/userguide/gradle_wrapper.html]
- recommended way to execute any Gradle build
  - invokes gradle with a declared version (vs randomnly installed one in OS).
    (robust builds)
  - invokes with a declared version of Gradle.

- Workflow:
    - set up a new Gradle project
    - add Wrapper to new project
      (a gradle runtime must be instaled)
      $ gradle wrapper \
        --gradle-version 5.1 \      optional
        --distribution-type bin  \  optional
        --gradle-distribution-url ...  optional
        --gradle-distribution-sha256-sum  ... optional

    The SHA256 hash sum used for verifying the downloaded Gradle distribution.


      → Task :wrapper
      →
      → BUILD SUCCESSFUL in 0s
      → 1 actionable task: 1 executed
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      .
      ├── build.gradle
      ├── settings.gradle
      ├──ºgradle                           º←  generated dir. to be added to git
      │  º└── wrapper                      º
      │  º    ├── gradle-wrapper.jar       º ← code for downloading the distro
      │  º    └── gradle-wrapper.propertiesº
      ├──ºgradlew    º   ← once generated, use it like $ ./gradlew build
      └──ºgradlew.batº
      gradle/wrapper/gradle-wrapper.properties  is generated
      with the information about the Gradle distribution:
       - server hosting the Gradle dist. Ex:
         distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip
       - type of Gradle dist.
         (default to -bin dist with only runtime -no sample code,docs,...)
       - The Gradle version used for executing the build.
         (default to local installed one)

    - Check generated wrapper files to "git",
      including the (small) jar files.
    - run a project with provided Wrapper
    ...
    - upgrade the Wrapper to new Gradle version when desired.

ºCustomizing the wrapperº
- built-in wrapper task exposes numerous options
  to bend the runtime behavior to your needs.
  build.gradle.kts:
  build.tasks.wrapper {
      distributionType = Wrapper.DistributionType.ALL
  }
- HTTP Basic Authentication (r*WARN: use only with TLS connections)
  alt 1: ENV.VARS:
  systemProp.gradle.wrapperUser=username
  systemProp.gradle.wrapperPassword=password
  alt 2: gradle/wrapper/gradle-wrapper.properties
  distributionUrl=https://username:password@somehost/path/to/gradle-distribution.zip

ºVerifying downloadº
@gradle/wrapper/gradle-wrapper.properties:
distributionSha256Sum=371cb9fbebbe9880d147f59bab36d61eee122854ef8c9ee1ecf12b82368bcf10

What's New v6
@[https://www.infoq.com/news/2020/01/gradle-releases-version-6/]
DDBB/persistence
Jooq
 SQL made simple
@[https://www.jooq.org/]


- vertx-jooq
  jOOQ-CodeGenerator to create vertxified DAOs and POJOs.
  Now with JDBC, async and reactive support!
@[https://github.com/jklingsporn/vertx-jooq]
Hibernate
@[https://quarkus.io/guides/hibernate-orm-panache-guide]
OpenJPA
@[https://openjpa.apache.org/]
reladomo
(Goldman Sachs)
@[https://github.com/goldmansachs/reladomo]
- enterprise grade (ORM) object-relational mapping framework for Java.
Snappy
Fast
de/compressor
@[https://github.com/xerial/snappy-java]
- Java port of the snappy http://code.google.com/p/snappy/
Cache
JCache
- Map-Like API optimized for caching.
- 1.0 drawbacks:
  - No async operations.
- Implemented by Hazelcast and others
JSON
JSON
- REF:JSON processing public review

Public review of JSR 374: Java API for JSON Processing (JSON-P) version 1.1 is now open.
This version is expected to be included in the release of J2EE 8 and keeps JSON-P current with JSON IETF standards. It includes support for:
    - JSON Pointer
    - JSON Patch
    - JSON Merge Patch
    - Query and transformation operations
    - Java 8 streams and lambdas
- JSON-P was introduced in 2013 with the release of J2EE 7, as
  an alternative to Gson and Jackson. It was designed to parse, generate,
  and query standard JSON documents.
  SR-367: Java API for JSON Binding (JSON-B), will also be included in the release of J2EE 8.
Example
tags: [JSON Parsing, HTTP GET/POST, TLS, Basic Authorization]
package com.mycomp.project1;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.json.JSONObject;

import java.security.cert.X509Certificate;
import java.util.Date;

import java.util.Scanner;

public class TestAPI˂JSONArray˃ {
    static String userpass = "operator1:ecllqy";
    private static SSLSocketFactory sslSocketFactory = null;

    private JSONObject sendPost(String url, String post_body, String token) throws Exception
    {
        URL obj = new URL(url);
        String basicAuth = "Basic " +
            javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes());

        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

        setAcceptAllVerifier((HttpsURLConnection)con); // TODO: WARN Add certificate validation.

        con.setRequestMethod("POST"); //add request header
        con.setRequestProperty("Content-Type", "application/json");
        con.setRequestProperty("Cache-Control", "no-cache");
        if (token.isEmpty()) { con.setRequestProperty("Authorization", basicAuth);
        } else               { con.setRequestProperty("Authorization", "Bearer "+token);
        }
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(post_body);
        wr.flush();
        wr.close();
        int responseCode = con.getResponseCode();

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        StringBuffer response = new StringBuffer();
        String inputLine; while ((inputLine = in.readLine()) != null) { response.append(inputLine); }
        in.close();
        return new JSONObject(response.toString()); //String myJSONStr
    }


    /*ºººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººº*/
    /**
     * Overrides the SSL TrustManager and HostnameVerifier to allow
     * all certs and hostnames.
     * WARNING: This should only be used for testing, or in a "safe" (i.e. firewalled)
     * environment.
     *
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    protected static void setAcceptAllVerifier(HttpsURLConnection connection) throws NoSuchAlgorithmException, KeyManagementException {
        // Create the socket factory.
        // Reusing the same socket factory allows sockets to be
        // reused, supporting persistent connections.
        if( null == sslSocketFactory) {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, ALL_TRUSTING_TRUST_MANAGER, new java.security.SecureRandom());
            sslSocketFactory = sc.getSocketFactory();
        }

        connection.setSSLSocketFactory(sslSocketFactory);

        // Since we may be using a cert with a different name, we need to ignore
        // the hostname as well.
        connection.setHostnameVerifier(ALL_TRUSTING_HOSTNAME_VERIFIER);
    }

    private static final TrustManager[] ALL_TRUSTING_TRUST_MANAGER = new TrustManager[] {
        new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {}
            public void checkServerTrusted(X509Certificate[] certs, String authType) {}
        }
    };

    private static final HostnameVerifier ALL_TRUSTING_HOSTNAME_VERIFIER  = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
}
Restassured:
Testing JSON REST
APIs

ºFULL JOURNEY == Simulate full (REST) API in expected orderº
˂dependency˃
    ˂groupId˃io.rest-assured˂/groupId˃
    ˂artifactId˃scala-support˂/artifactId˃
    ˂version˃3.0.6˂/version˃
    ˂scope˃test˂/scope˃
˂/dependency˃
˂dependency˃
    ˂groupId˃io.rest-assured˂/groupId˃
    ˂artifactId˃json-schema-validator˂/artifactId˃
    ˂version˃3.0.6˂/version˃
    ˂scope˃test˂/scope˃
˂/dependency˃
___________________________
package com.mycompany.myproject.mymodule;

import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.Matchers.*;

import static io.restassured.RestAssured.given;

import io.restassured.RestAssured;
import io.restassured.config.HttpClientConfig;
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import junit.framework.TestCase;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.SystemDefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.eclipse.jetty.http.HttpStatus;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.BeforeClass;

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;

import java.util.Base64;
import java.util.Map;

public class FullJourneyTest {

    // Custom regex matcher for RestAssured Framework
    public static classBºRegexMatcherºextendsºBaseMatcher˂Object˃º{
        private final String regex;
        public BºRegexMatcherº(String regex){ this.regex = regex; }
       º@Overrideºpublic booleanºmatchesº(Object o){ return ((String)o).matches(regex); }
       º@Overrideºpublic voidºdescribeToº(Description description){
            description.appendText("matches regex=");
        }
        public staticBºRegexMatcherº matches(String regex){ return newBºRegexMatcherº(regex); }
    }

     public static classGºBase64MatcherºextendsºBaseMatcher˂Object˃º{
        public Base64Matcher(){}
       º@Overrideºpublic booleanºmatchesº(Object o){
            try {
                Base64.getDecoder().decode((String)o);
                return true;
            }catch (Exception e){
                return false;
            }
        }

       º@Overrideºpublic voidºdescribeToº(Description description){
            description.appendText("can be parsed as Base64");
        }

        public static Base64Matcher isBase64Encoded(){
            return new Base64Matcher();
        }
    }
    private static final String AUTH_HEADER_VALUE = "Bearer " + ServerConfig.apiKey;

    protected static RequestSpecification setupCommonHeaders() {
        return given().header("Authorization", AUTH_HEADER_VALUE)
                      .header("Accept"       , "application/json")
                      .header("content-type" , "application/json;charset=utf-8")
        .log().all();
    }


    final String
        NAME="COMMUNITY_1", SYMBOL="SY1";

    Response response;
  Qº@BeforeClassº
    public static void setup() {
        RestAssured.port     = ServerConfig.serverPort;
        RestAssured.basePath = "/";
        RestAssured.baseURI  = "http://localhost";

        HttpClientConfig clientConfig = RestAssured.config().getHttpClientConfig();
        clientConfig = clientConfig.httpClientFactory(new HttpClientConfig.HttpClientFactory() {
            @Override
            public HttpClient createHttpClient() {
                HttpClient rv =  new SystemDefaultHttpClient();
                HttpParams httpParams = rv.getParams();
                //  Wait 5s max for a connection
                HttpConnectionParams.setConnectionTimeout(httpParams, 5 * 1000);
                // Default session is 60s
                HttpConnectionParams.setSoTimeout(httpParams, 60 * 1000);
                return rv;
            }
        });
        // This is necessary to ensure, that the client is reused.
        clientConfig = clientConfig.reuseHttpClientInstance();
        RestAssured.config = RestAssured.config().httpClient(clientConfig);
    }

  Qº@Testº
    public void A010_PutNewCommunityAndNewUserForPendingToMineCommunity() {
        String jsonBody =
            "{ " +
                " \"name\": \""+NAME+"\", " +
                " \"symbol\": \"" + SYMBOL + "\","
            "}";
        response = setupCommonHeaders().body(jsonBody).when().ºpost("/Route/To/REST/API/01")º;
        System.out.println(response.body().prettyPrint());
        response.then()
            /* ºget sure JSON serializer do not include extra (maybe sensitive) infOº */
            .body("size()", Oºis(5)                          º)
            .body("id"    , Oºnot(isEmptyString())           º)
            .body("pubkey", Oºnot(isEmptyString())           º)
            .body("pubkey", BºRegexMatcherºOº.matches("^{65}$")º)
            .body("pubkey", OºBase64Matcher.isBase64Encoded()º)
            .body("name"  , OºequalTo(NAME)                  º)
            .body("symbol", OºequalTo(SYMBOL)                º)
            .statusCode(HttpStatus.ACCEPTED_202);
        String BºNEW_ID = response.getBody().jsonPath().get("id")º;

        // Next related test to execute synchronously after fetching NEW_ID
        String jsonBody =
            "{ " +
                B*" \"FK_ID\": \""+NEW_ID+"\", " +*
                ...
            "}";

        response = setupCommonHeaders().body(jsonBody).when().ºpost("/Route/To/REST/API/02")º;
        ...
    }

}
BDD Serenity Testing
@[https://serenity-bdd.github.io/theserenitybook/latest/index.html]

Serenity BDD is an open source library that aims to make the idea of living 
documentation a reality.

Serenity BDD helps you write cleaner and more maintainable automated acceptance 
and regression tests faster. Serenity also uses the test results to produce 
illustrated, narrative reports that document and describe what your application 
does and how it works. Serenity tells you not only what tests have been 
executed, but more importantly, what requirements have been tested.

One key advantage of using Serenity BDD is that you do not have to invest time 
in building and maintaining your own automation framework.

Serenity BDD provides strong support for different types of automated 
acceptance testing, including:

    Rich built-in support for web testing with Selenium.

    REST API testing with RestAssured.

    Highly readable, maintainable and scalable automated testing with the 
Screenplay pattern.

The aim of Serenity is to make it easy to quickly write well-structured, 
maintainable automated acceptance criteria, using your favourite BDD or 
conventional testing library. You can work with Behaviour-Driven-Development 
tools like Cucumber or JBehave, or simply use JUnit. You can integrate with 
requirements stored in an external source (such as JIRA or any other test cases 
management tool), or just use a simple directory-based approach to organise 
your requirements.

What's new
JAVA 14 (future)
https://www.infoq.com/news/2019/12/java14-feature-freeze/
JAVA 13 (future)
@[https://www.infoq.com/news/2019/06/java13-feature-freeze/]

@[https://developers.redhat.com/blog/2019/06/27/shenandoah-gc-in-jdk-13-part-1-load-reference-barriers/]
@[https://developers.redhat.com/blog/2019/06/28/shenandoah-gc-in-jdk-13-part-2-eliminating-the-forward-pointer-word/]
@[https://developers.redhat.com/blog/2019/07/01/shenandoah-gc-in-jdk-13-part-3-architectures-and-operating-systems/]
JAVA 11(LTS) 2018/09
@[https://www.journaldev.com/24601/java-11-features]
@[https://www.infoq.com/news/2018/09/java11-released]

new major features:
- Autocompilation(JEP 330). Next code will execute:
  $ java someFile.java

- New string methods:
  - isBlank(): true for Empty or only white spaces strings
  - lines()  : returns string[] that collects all substrings split by lines.
    System.out.println(
       "JD\nJD\nJD".str.lines().collect(Collectors.toList())
    );
  - strip()         : similar to trim() but unicode-aware
    stripLeading()
    stripTrailing()
  - repeat(int n)     : repeats string  n times.


- Local-Variable Syntax for Lambda Parameters (JEP 323)
  (var s1, var s2) -˃ s1 + s2
  - While it's possible to  just skip the type in the lambda
    it becomes a need when for annotations like @Nullable

- Nested Based Access Control
  (fix some issues when using (discouraged-)reflection.

- Dynamic Class-File Constants(JEP 309)
  - class-file format now extends support a new constant pool form:
    -ºCONSTANT_Dynamicº, reduce the cost and disruption of developing
      new forms of materializable class-file constraints.

- Epsilon: A No-Op Garbage Collector(JEP 318):
  - Experimental
  - Unlike the JVM GC which is responsible for allocating memory
    and releasing it, Epsilon only allocates memory. Useful for:
    -ºExtremely short lived jobsº
    - Performance testing
    - Memory pressure testing
    - VM interface testing
    - Last-drop latency improvements
    - Last-drop throughput improvements

- Remove the JavaEE and CORBA Modules(JEP 320):
  java.xml.ws, java.xml.bind, java.activation,
  java.xml.ws.annotation, java.corba, java.transaction,
  java.se.ee, jdk.xml.ws, jdk.xml.bind
 RºWARNº: EE modules contain the support for JAXB and SOAP,
          still in relatively widespread use.
        - Check carefully whether build scripts need to
          be modified.

- Flight Recorder(JEP 328)
  - profiling tool gathering diagnostics and profiling data
  - negligible performance overhead (˂1%):
    -ºCan be used in productionº

- HTTP Client (JEP 321)
  - HTTP/1.1,ºHTTP/2 and WebSocketsº
  - Designed to improve overall performance of
    sending requests by a client and receiving
    responses from the server.

- TLS 1.3

- Convenient Reading/Writing Strings to/from Files
  - readString()
  - writeString()
  Path path = Filesº.writeStringº(
    Files.createTempFile("test", ".txt"),
    "This was posted on JD");
  System.out.println(path);
  String s = Filesº.readStringº(path);
  System.out.println(s); //This was posted on JD

- ChaCha20,Poly1305 Crypto (JEP 329)
  - implemented in the SunJCE provider.

- Improve (string and array)Aarch64 processor Intrinsics(JEP 315)
  - implement also new intrinsics for
    (java.lang.Math) sin, cos, and log functions.

- ZGC:(JEP 333)
  - Scalable Low-Latency Garbage Collector
  - Experimental
  - low latency GC.
  - sub-10ms pause times, less than 15% perf.penalty.
- Deprecate Nashorn JS Engine(JEP 335)
JAVA 10 (2018/03)
- Application Data-Class Sharing (JEP ???)
  -  extends existing Class-Data Sharing ("CDS")
     for allowing application classes to be placed in
     the shared archive in order to improve startup
     and footprint.
- Parallel Full GC for G1
  - improves G1 worst-case latencies
- Garbage Collector Interface
  - improves source code isolation of different GCs.
- Consolidate JDK Forest into a Single Repository
- Local-Variable Type Inference
  - declarations of local variables with initializers
  - introducesºvarº
- Remove Native-Header Generator Tool (javah)
  superseded by superior functionality in javac.
- Thread-Local Handshakes:
  - Allows to execute a callback on threads without
    performing a global VM safepoint. Makes it both
    possible and cheap to stop individual threads and
    not just all threads or none.
- Time-Based Release Versioning
- Root Certificates, providing a default set of root
  CAs in the JDK.
- Heap Allocation on Alternative Memory Devices:
  - enables the HotSpot VM to allocate the Java object
    heap on an alternative memory device, such as an
    NV-DIMM, specified by the user.
- Experimental Java-Based JIT Compiler Graal:
  - Linux/x64 platform only

- Additional Unicode Language-Tag Extensions

- Removed Features and Options:
JAVA 9(2017/09)
- Java Platform Module System:
  - based on Project Jigsaw
  - divides the JDK into a set of modules for
    combining at run, compile, or build time.
  - enabling understanding of dependencies across modules.
  - allows developers to more easily assemble and
    maintain sophisticated applications.
  - allows to scale down to smaller devices.
  - improves security and performance.
  - aspects include:
    - application packaging
    - JDK modularization
    - reorganizing source code into modules.
    - Build system is enhanced to compile modules
      and enforce module boundaries at build time.
  (Java 9 allows illegal reflective access to help migration)

- ahead-of-time (AoT) compilation (experimental)
  - improve startup time, with limited impact on peak performance.
-ºREPL (read-eval-print loop)º
  - jShell: interactively evaluates statements "a la script".
    - tab completion
    - automatic addition of needed terminal semicolons.
    - jShell API for IDE integration.

  - jShell: interactively evaluates statements "a la script".

- Streams API Enhancements
  - Java 8 Stream API allows processing data declaratively
    while leveraging multicore architectures.
  - Java 9 adds methods to conditionally take and drop items
    from Stream, iterate over Stream elements, and create a
    stream from a nullable value while expanding the set of
    Java SE APIs that can serve as Streams sources.

- Code cache can be divided in Java 9
  - code cache can now be divided into segments to
    improve performance and allow extensions such as
    fine-grained locking resulting in improved sweep
    times
- (Datagram Transport Layer Security) DTLS security API
  - prevent eavesdropping, tampering, and message forgery
    in client/server communications.

- Java 9 deprecates and removes:
  - Applet API and appletviewer (alternative: Java Web Start)
  - Concurrent Mark Sweep (CMS) GC.
  - JVM TI (Tool Interface) hprof (Heap Profiling) agent,
    superseded in the JVM.
  - jhat tool, obsoleted by superior heap visualizers and analyzers.
GraalVM
@[http://www.graalvm.org/]
@[https://technology.amis.nl/2018/11/23/comparing-jvm-performance-zulu-openjdk-openjdk-oracle-jdk-graalvm-ce/]
@[https://www.reddit.com/r/java/comments/acarqq/graalvm_in_2018/]

- Graal: How to Use the New JVM JIT Compiler in Real Life
  @[https://www.infoq.com/presentations/graal-jvm-jit/]
Quarkus
GraalVM
Framework
@[https://quarkus.io/guides/]
@[https://quarkus.io/guides/kogito-guide]
@[https://quarkus.io/guides/using-vertx.html]
..
@[https://www.infoq.com/news/2019/03/redhat-release-quarkus]

Extracted from "Hibernate with Panache" by Emmanuel Bernard.
""" Quarkus is Supersonic Subatomic Java. extremely fast with low memory footprint""".
@[https://quarkus.io/guides/hibernate-orm-panache-guide]
Hibernate ORM is the de facto JPA implementation and offers you the full
breadth of an Object Relational Mapper. It makes complex mappings possible,
but it does not make simple and common mappings trivial. Hibernate ORM with
Panache focuses on making your entities trivial and fun to write in Quarkus.
Tech Radar
LMAX Disruptor
High Perf Inter-Thread
 Messaging Library
@[https://lmax-exchange.github.io/disruptor/]

See also:
@[https://www.infoq.com/articles/High-Performance-Java-Inter-Thread-Communications/]

@[https://www.infoq.com/news/2013/05/lmax-zing]
LMAX Exchange Getting Up To 50% Improvement in Latency From Azul's Zing JVM
Interesting points about GC tunning.
Java Value Types proposal
@[https://www.infoq.com/news/2017/11/ValueTypesNov10]
            ┌────────────────────────────┬───────────────────────────────────────
            │ "NOW" (2019─12)            │ "FUTURE" 
            │ + primitive types          │ + primitive types
            │ + object references:       │ + object references:
            │ ─ NO low─level mem.control │ + Value types
            │   (deliberately)           │   
────────────┼────────────────────────────┼───────────────────────────────────────
PROS:       │ ─ Great simplicity         │ ─ Memory layout efficiency
            │                            │ ─ removes the need for
            │                            │   a full object header
            │                            │   for each item of composite data.
            │                            │ ─ header removal 
            │                            │   =→ instance metadata removal
────────────┼────────────────────────────┼───────────────────────────────────────
CONS:       │ performance penalties      │ ─ Higher complexity
            │ ─ indirections in arrays   │ ─ object's identity is lost
            │ ─ cache misses.            │ ─ new bytecodes needs to be introduced
────────────┴────────────────────────────┴───────────────────────────────────────
Tribe
reliable multicast
@[http://tribe.ow2.org/]
- Unlike JGroups, Tribe only targets reliable multicast
 (no probabilistic delivery) and is optimized for cluster
 communications.
JGroups multicast
@[http://www.jgroups.org/]
- toolkit for reliable multicast communication.
- point-to-point FIFO communication channels (basically TCP)
- Targets high performance cluster environments.

- Unlike JGroups, Tribe only targets reliable multicast
  (no probabilistic delivery) and is optimized for
  cluster communications.
Apache MINA
(Netty Alter.)
Apache MINA vs Netty: https://www.youtube.com/watch?v=A2pWsxPWJuc

Apache MINA is a network application framework which helps users develop high
performance and high scalability network applications easily. It provides an
abstract event-driven asynchronous API over various transports such as TCP/IP
and UDP/IP via Java NIO.

Apache MINA is often called:
- NIO framework library,
- client server framework library, or
- a networking socket library

Apache MINA comes with many subprojects :
- Asyncweb : An HTTP server build on top of MINA asynchronous framework
- FtpServer : A FTP server
- SSHd : A Java library supporting the SSH protocol
- Vysper : An XMPP server
OSV.io
- @[http://osv.io/]
  versatile modular unikernel designed to run unmodified Linux 
applications securely on micro-VMs in the cloud. Built from the ground up for 
effortless deployment and management of micro-services and serverless apps, 
with superior performance. (Includes CRaSH shell)
Non-Classiffied
Google Guava
JS transpilers
- JSweet.org: Java to Javascript transpiler:

@[http://teavm.org/]
  TeaVM is an ahead-of-time compiler for Java bytecode that emits JavaScript
  and WebAssembly that runs in a browser. Its close relative is the well-known
  GWT. The main difference is that TeaVM does not require source code, only
  compiled class files. Moreover, the source code is not required to be Java,
  so TeaVM successfully compiles Kotlin and Scala.

- @[https://www.infoq.com/news/2019/05/j2cl-java-javascript-transpiler/]
"https://en.wikipedia.org/wiki/Java_virtual_machine#Compilation_to_JavaScript
""Main JVM bytecode to JavaScript compilers are TeaVM,[20] the compiler
contained in Dragome Web SDK,[21] Bck2Brwsr,[22] and j2js-compiler.[23]"""
Crypto.API(JCA)
- See also:
  Bounce Castle FIPS JCA provider
Javalin
Simple Kotlin/Java
web framework 
@[https://javalin.io]
- Inspired by Javascript KOA.js framework

Ex: Declare server and API in the same place
  | import io.javalin.ApiBuilder.*;
  | import io.javalin.Javalin;
  |
  | Javalin app = Javalin.create(config -˃ {
  |     config.defaultContentType = "application/json";
  |     config.addStaticFiles("/public");
  |     config.enableCorsForAllOrigins();
  | }).routes(() -˃ {
  |     path("users", () -˃ {
  |         get(UserController::getAll);
  |         post(UserController::create);
  |         path(":user-id", () -˃ {
  |             get(UserController::getOne);
  |             patch(UserController::update);
  |             delete(UserController::delete);
  |         });
  |         ws("events", userController::webSocketEvents);
  |     });
  | }).start(port);
JNR(JNI/UNIX friendly)
( used by Netty and others...)
-@[https://github.com/jnr/jnr-ffi]
   load native libraries without writing JNI code by hand, or using tools such as SWIG.
-@[https://github.com/jnr/jnr-unixsocket]
   jnr-unixsocket: UNIX domain sockets (AF_UNIX) for Java
-@[https://github.com/jnr/jnr-enxio]
   Java Native Runtime Enhanced X-platform I/O
-@[https://github.com/jnr/jnr-x86asm]
   Pure java x86 and x86_64 assembler
-@[https://github.com/jnr/jnr-a64asm]
  AArch64 assembler for the Java Native Runtime
-@[https://github.com/jnr/jnr-process]
  A ProcessBuilder look-alike based entirely on native POSIX APIs
-...
Modules (1.9+)
JSR 376
- implemented within project Jigsaw.

module:
- named, self-describing collection of code and data.
-  Its code is organized as a set of packages containing types
   (JVM classes and interfaces).
- its data includes resources and other kinds of static information.
Java Erasure
- Type Erasure is a technique employed
  the Java compiler to support the use of Generics.
@[https://developer.ibm.com/recipes/tutorials/java-language-type-erasure/]
Eclipse Microprofile
@[https://dzone.com/articles/microprofile-5-things-you-need-to-know]

- launched at JavaOne 2016 to address the shortcomings in the Enterprise Java microservices space.

- MicroProfile specifies a collection of Java EE APIs and technologies which together
  form a core baseline microservice that aims to deliver application portability across multiple runtimes.

- MicroProfile 1.0 spec includes a subset of the 30+ Java Enterprise specifications:
  - JAX-RS 2.0 for RESTful endpoints
  - CDI 1.1 for extensions and dependency injection
  - JSON-P 1.0 for processing JSON messages.

- MicroProfile 1.2  (September 2017) include:
  - Configuration 1.1
  - Fault Tolerance
  - JWT
  - Metrics
  - Health Check

- MicroProfile 2.0 (Future). It is expected it will align all APIs to Java EE 8.

- vendors runtime support:
  - WebSphere Liberty IBM
  - TomEE from Tomitribe
  - Payara
  - RedHat's WildFly Swarm
  - KumuluzEE.

- Community support:
  - London Java Community
  - SOUJava
  - ...

- key code sample consists of four microservices and a front-end application.
  Vendor            |     JAR |      StartUp
                    | size/Mb | Time in Secs
  WebSphere Liberty |   35    |            7
  WildFly Swarm     |   65    |            6
  Payara            |   33    |            5
  TomEE             |   35    |            3
  KumuluzEE*        |   11    |            2

- CDI-Centric Programming Model
  - Context and Dependency Injection specification
  - Two of its most powerful features are interceptors and observers.
    - Interceptors perform cross-cutting tasks that are orthogonal to business logic
      such as auditing, logging, and security
    - The baked-in event notification model implements the observer
      pattern to provide a powerful and lightweight event notification system
      that can be leveraged system-wide.