Saturday, March 30, 2019

Java EE 8 Application Development book

David R. Heffelfinger - Java EE 8 Application Development-Packt Publishing (2017)

I am going through the examples of the book, using WLS (it supports only Java EE 7, unfortunately), and IntelliJ 2019.1

here how to setup your environment (very easy!) :

Code is here

You can run also on Wildfly 16 which supports Java EE 8

Java EE 8 Javadoc

Friday, March 29, 2019

bash script cheatsheet

Tuesday, March 26, 2019

Camel rediscovered

testing rest with

Old posts:

Helm tutorials on Katacoda

I have been through some youtube tutorials on Helm but I found them too blablaistic. I like essential, crisp and down to earth presentations, not all-encompassing philosophical sermons.

curl | bash
helm init
helm repo update
kubectl get pods -n kube-system
helm version

in Chart.yaml there is basically nothing (version and chartname)

in equirements.yaml there are dependencies

in templates/configmap.yaml the ConfigMap

in templates/service.yaml the Service Definition (with port/nodePort)

in templates/pv.yaml the PersistenVolume

helm dependency update lets-chat

helm inspect lets-chat

helm install lets-chat --name demo -f my_values.yml --debug --dry-run

helm install lets-chat --name demo --namespace demo -f my_values.yml

helm list

helm status demo

kubectl get pods -n demo

sed -i 's/0.4.7/0.4.6/g' lets-chat/Chart.yaml

helm upgrade demo lets-chat --set replicas=2

helm history demo

helm rollback demo 1

maven the reference guide the complete reference usual excellent Baeldung tutorial to understand those obfuscated concepts of "lifecycle", "phase", "goal"

Monday, March 25, 2019

Book: java by comparison by Simon Harrer, Jörg Lenhard, Linus Dietz

Interesting book, concise and a breeze to read

Source code is here

My first (not very functional) implementation of FizzBuzz:


public class ConsoleBasedFizzBuzz implements FizzBuzz {
    public static void main(String[] args) {
        FizzBuzz fizzBuzz = new ConsoleBasedFizzBuzz();
        fizzBuzz.print(1, 100);

    private static void accept(int i) {
        StringBuffer result = new StringBuffer();
        if (i % 3 == 0) result.append("Fizz");
        if (i % 5 == 0) result.append("Buzz");
        if (result.length() == 0) result.append(i);

    public void print(int from, int to) {
        IntStream.range(from, to).forEach(ConsoleBasedFizzBuzz::accept);

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."

Avoid Unnecessary Comparisons
Avoid Negations
Return Boolean Expressions Directly
Simplify Boolean Expressions
Avoid NullPointerException in Conditionals
Avoid Switch Fallthrough
Always Use Braces
Ensure Code Symmetry
Replace Magic Numbers with Constants
Favor Enums Over Integer Constants
Favor For-Each Over For Loops
Avoid Collection Modification During Iteration
Avoid Compute-Intense Operations During Iteration
Group with New Lines
Favor Format Over Concatenation
Favor Java API Over DIY
Remove Superfluous Comments
Remove Commented-Out Code
Replace Comments with Constants
Replace Comments with Utility Methods
Document Implementation Decisions
Document Using Examples
Structure JavaDoc of Packages
Structure JavaDoc of Classes and Interfaces
Structure JavaDoc of Methods
Structure JavaDoc of Constructors
Use Java Naming Conventions
Follow Getter/Setter Conventions for Frameworks
Avoid Single-Letter Names
Avoid Abbreviations
Avoid Meaningless Terms
Use Domain Terminology
Fail Fast
Always Catch Most Specific Exception
Explain Cause in Message
Avoid Breaking the Cause Chain
Expose Cause in Variable
Always Check Type Before Cast
Always Close Resources
Always Close Multiple Resources
Explain Empty Catch
Structure Tests Into Given-When-Then
Use Meaningful Assertions
Expected Before Actual Value
Use Reasonable Tolerance Values
Let JUnit Handle Exceptions
Describe Your Tests @DisplayName @Disabled
Favor Standalone Tests
Parametrize Your Tests @ParameterizedTest @ValueSource
Cover the Edge Cases
Split Method with Optional Parameters
Favor Abstract Over Concrete Types
Favor Immutable Over Mutable State
Combine State and Behavior
Avoid Leaking References (defensive copying)
Avoid Returning Null
Favor Lambdas Over Anonymous Classes
Favor Method References Over Lambdas
Avoid Side Effects
Use Collect for Terminating Complex Streams
Avoid Exceptions in Streams
Favor Optional Over Null (Optional.ofNullable())
Avoid Optional Fields or Parameters
Use Optionals as Streams

Google Java Style Guide

Automate Your Build
Favor Logging Over Console Output
Minimize and Isolate Multithreaded Code
Use High-Level Concurrency Abstractions
Speed Up Your Program

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;


public class JunitAssertionsTest {

    public void testException() {
        Executable when = () -> pippo();
        Assertions.assertThrows(IOException.class, when);

    private void pippo() throws IOException {
        throw new IOException("ciao");

spotbugs former findbugs

  <!-- overwrite dependency on spotbugs if you want to specify the version 
   of spotbugs -->

mvn spotbugs:spotbugs

this generates a file with a report:


the report is hard to read honestly, but there are many interesting remarks

Sunday, March 24, 2019

Java 12 is out

Download :

Documentation :

quick "what's new in Java 12" my the good Marco Behler

Nothing really revolutionary as far as I can see....mostly "enhanced switches" are cool

To use Java 12 you must install Intellij 2019.1

Saturday, March 23, 2019

Friday, March 22, 2019

Running Windows in Windows

You can download an .ova appliance for VirtualBox here , unzip it, then open it in VistualBox , create a "shared" folder to exchange files with your host....

a very powerful and safe way to experiment without risking the health of your main Windows installation.

The images last only for 3 months, that's good enough for me :)

I see that also a Hyper-V image is available...

Thursday, March 21, 2019

Quarkus and Microservices

I receive this email from my friend Rob and I gladly publish it:

I see a lot of migration work going on in the future from existing JEE solutions, broken down to microservices and moving to native k8s images compiled with GraalVM.

The complete JEE programming model gets a fresh look towards microservices.

Go through this presentation

get the ebook

and the github

and finally this will all go to this, quarkus "Quarkus is a Kubernetes Native Java framework tailored for GraalVM and HotSpot, crafted from best-of-breed Java libraries and standards."

This is the fastest realtime hot replace developer solution I have seen "quarkus:dev", this outperforms spring boot devtools

Tuesday, March 12, 2019

IntelliJ, Eclipse and Java 11

you must install IDEA 2018.2 or greater. 2018.1 will not work, it supports only Java 10. It's a 500 MB monster so be patient. download 2018.3.5 here

then configure the platform JDK with your installed JDK 11 (of course you must have installed this JDK from Oracle or OpenJDK!), with ALT-SHIFT-CONTROL-S (project structure/SDKs)

then configure Java 11 level (File/Project Structure/Modules and File/Project Structure/Project)

also don't forget the bytecode level (File/Settings/Java Compiler):

If you get the "invalid source release: 11" , it's possible that you misconfigured the "platform JDK"

For Eclipse it's much easier: install Eclipse 2018-09 (4.9), then install this add-on:

make sure you configure the JDK in the "installed JRA" preferences tab,

and when you create a new project, select jdk11 and create the module-info by default.
All works fine.

GNOME desktop on Centos 7 docker

open Git Bash

winpty docker run -ti --name centos centos bash
#run all the commands to install GNOME
docker start centos
winpty docker exec -ti centos bash

#uptime gives you the number of days the HOST was up, not the container

Monday, March 11, 2019, the online kubernetes yaml generator

I agree with every word written here:

beyond a very basic deployment, working directly with yaml files is suicidal.

I will explore this yipee and see if I can use it regularly, as replacement for a really primitive "vi mypod.yml"

Sunday, March 10, 2019

Kubernetes Java client to generate yaml files for you

If you - like me - hate having to type YAML by hand, you can take advantage of a pre-built K8S Model and YAML serialization tool:


import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.internal.SerializationUtils;

public class KubernetesClientTest {
 public static void main(String[] args) throws JsonProcessingException {
  String yaml = SerializationUtils.dumpAsYaml(new DeploymentBuilder().withNewSpec().endSpec().build());
  KubernetesClient client = new DefaultKubernetesClient();
  Pod pod = new Pod();
  String podyaml = SerializationUtils.dumpAsYaml(pod);


The model is incredibly rich.... one has only to learn how to use it...

good presentation of Azure Kubernetes

The session is available also here
and here you can download the slides (on the movie the resolution is quite lame)

What is ?

Azure DevSpaces
it's a direct tie between Visual Studio and AKS, with debugging of containers.

Azure Container Registry

Namespace-level RBAC security access, using AD groups.

Key Vaults contain Kubernetes and Application secrets (NO certificates in container!)

ACI Azure Container Instances


Training modules: Introduction to Azure an introduction to Azure Services

Friday, March 8, 2019

Quarkus Kubernetes and Katacoda

I open a Katacoda lab with minikube in it

First step:

git clone
cd getting-started
mvn compile quarkus:dev

now open a new terminal and "curl http://localhost:8080/hello"

cd quarkus-quickstarts/
cd getting-started-kubernetes/

#install graalvm
mkdir /root/graalvm
cd /root/graalvm
curl -L -o graalvm-ce-1.0.0-rc13-linux-amd64.tar.gz
tar xvfz graalvm-ce-1.0.0-rc13-linux-amd64.tar.gz
export GRAALVM_HOME=/root/graal/graalvm-ce-1.0.0-rc13

mvn package -Pnative

here I get plenty of compilation errors, so I am giving up...

GraalVM is available here
and more instructions here

Kubernetes cheat sheet 3

Network Policies

kubectl get networkpolicy

kubectl describe networkpolicy

Name:         payroll-policy
Namespace:    default
Created on:   2019-03-08 08:47:51 +0000 UTC
Labels:       <none>
Annotations:  <none>
  PodSelector:     name=payroll
  Allowing ingress traffic:
    To Port: 8080/TCP
      PodSelector: name=internal
  Allowing egress traffic:
    <none> (Selected pods are isolated for egress connectivity)
  Policy Types: Ingress

kind: NetworkPolicy
  name: internal-policy
  namespace: default
      name: internal
  - Egress
  - Ingress
    - {}
  - to:
    - podSelector:
          name: mysql
    - protocol: TCP
      port: 3306

  - to:
    - podSelector:
          name: payroll
    - protocol: TCP
      port: 8080

VOLUMES good article

kind: PersistentVolume
apiVersion: v1
  name: task-pv
    storage: 100Gi
    - ReadWriteOnce
    volumeID: vol-867g5kii
    fsType: ext4

Wednesday, March 6, 2019

Exploring VS Code plugin for Kubernetes

Crafting yaml by hand is not ideal.

Install VS Code:

the simply type "code" ( I could not find the shortcut in Applications/Programming)

ctrl-shift-X , type "Kubernetes", and install the first one (by Microsoft)

and also "Kubernetes Tools" source code here

Of course you must have AKS CLI installed

When you start "code" and click on the Kubernetes icon on the left, you get all the clusters listed in /home/centos/.kube/config file

Tuesday, March 5, 2019

Kubernetes cheat sheet 2


kubectl get pods --namespace=dev
kubectl get pods --namespace=default

kubectl config set-context $(kubectl config current-context) --namespace=dev


kubectl create configmap myconfigmap --from-literal=APP_COLOR=blue
kubectl create -f myconfigmap.yml

apiVersion: v1
kind: ConfigMap
  name: myconfigmap
  APP_COLOR: blue
  APP_MODE: prod

then you inject into a container definition using
- configMapRef
    name: myconfigmap

kubectl get configmaps
kubectl describe configmaps db-config


kubectl create secret generic mysecret --from-literal=mykey=myvalue

apiVersion: v1
kind: Secret
  name: app-secret
  DBHost: mysql
  DBUser: root
  DBPassword: password

kubectl create -f secret_data.yaml


you can declare at Pod or container level:

    runAsUser: 1000
      add: ["MAC_ADMIN"]

#check which user runs the container
kubectl exec ubuntu-sleeper whoami

kubectl create serviceaccount dashboard-sa
kubectl get serviceaccount
kubectl describe serviceaccount dashboard-sa
kubectl describe secret dashboard-sa-account-token

curl https://myip/api -insecure --header "Authorization: Bearer PASTE_THE_TOKEN_HERE"

#change serviceaccount for a deployment
kubectl --record deployment.apps/web-dashboard set serviceaccount dashboard-sa


    memory: "1Gi"
    cpu: 1

Taints and Tolerations

kubectl taint nodes node-name key=value:taint-effect

taint-effect can be: NoSchedule, PreferNoSchedule, NoExecute

key=value can be app=blue

- key: "app"
operator: "Equal"
value: "blue"
effect: "NoSchedule"

to remove taint:

kubectl taint nodes master


  size: Large

where size is a key and Large a value

to label a node:
kubectl label node mynode key=value

  - matchExpressions:
    - key: color
   operator: In
   - blue

Readiness Probe

in the spec/containers/ section for each container:

    path: /api/ready
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5

beside httpGet you can have: "tcpSocket: port:", "exec: command:"

Liveness Probe

    path: /api/ready
    port: 8080

Sunday, March 3, 2019

Kubernetes cheat sheet 1

alias k=kubectl


kubectl run nginx --image=nginx

kubectl create -f nginx.yml

apiVersion: v1
kind: Pod
  name: nginx-pod
    - name: nginx-container
      image: nginx

kubectl describe pods nginx-pod

kubectl get pods -o wide

kubectl edit pod nginx-pod

kubectl delete pod nginx-pod

kubectl get pod pod-name -o yaml > pod-definition.yaml

Replication Controller

kubectl create -f rc-definition.yml

apiVersion: v1
kind: ReplicationController
  name: nginx
    replicas: 3
      app: nginx
        name: nginx
          app: nginx
          - name: nginx
            image: nginx
              - containerPort: 80

kubectl get rc

Replica Set

kubectl create -f rs-definition.yml

apiVersion: apps/v1
kind: ReplicaSet
  name: frontend
    app: guestbook
    tier: frontend
# modify replicas according to your case
  replicas: 3
      tier: frontend
      tier: frontend
        - name: php-redis

kubectl get replicaset

kubectl describe replicaset

kubectl replace

kubectl scale --replicas=3 rs/myrs

kubectl get rs myrs -o yaml


kubectl create -f mydeployment.yml
apiVersion: apps/v1
kind: Deployment
  name: nginx-deployment
    app: nginx
    replicas: 3
        app: nginx
        app: nginx
        - name: nginx
          image: nginx:1.7.9
            - containerPort: 80

kubectl get all

An overall good explanation of Kubernetes is here

Excellent Kubernetes Developer Certification training on Udemy for only 11 USD !

Mumshad Mannambeth is a fantastic trainer, focusing on concepts but analyzing every detail in a very visual manner. Exam Homepage exam details

Candidate Handbook:

Exam Tips:

Hands On Full Stack Development with Spring Boot 2.0 and React by Juha Hinkula

you are warned: "incula" is a terrible word in Italian, so if you talk about this book with Italians you should be very careful.

Better to install MariaDB.

If you want to change root password:

cd D:\Program Files\MariaDB 10.3\bin

mysqladmin.exe --user=root --password=oldpassword password "newpassword"

to connect

mysql -u root -p

create database cardb

For chapter04, password can be replaced with "pippo" (bcrypted the value is $2a$04$ryGKh2NmcAj.dRzU/MDDVeTApJAMrfbyzVVGlclK8u/HLrTamBH5m )

curl -u admin:pippo http://localhost:8080/api (this will fail because you need a valid JWT token)

then the POST to localhost:8080/login must have a body {"username": "admin", "password": "pippo" }

and in the Authorization header you get Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTU1MTY0Nzg3OX0.DlHNCsxwasv4wjZcar2afWWx5ispQWFfIfL6NEnsrDYucLqPQWO53WcmUUDJfw12t0ux-9P-HzwF8qKnd1SNDg