Sunday, May 19, 2019

JAXRS all-in-one

All annotations are summarized here

"Base URL for any web application is:


Append tag from web.xml with Base URL that forms:


Append class-level @Path(“class-level”) annotation and then method-level @Path(“method-level”) annotation that forms:


extends Application







@PathParam("isbn") String isbn



It's all very clear apart @Context... read here to understand @Context

this for SecurityContext :

and some more coding examples here

Friday, May 17, 2019

More interesting readings on quarkus and microprofiles

I reveive from my friend Rob:

This will soon overhaul Spring Boot. Look how they fast grow with integrating all enterprise patterns on Quarkus. This community is the driver

Look at this suberb documentation, almost covering everything you need

and then this amazing reactive streaming doc

this will leave spring boot behind really soon

Worth reading is also

Interesting also eclipse.microprofile running on Open Liberty

Thursday, May 16, 2019

Jooq and QueryDSL as alternatives to JPQL, Panache,

HQL (and JPQL) both suck because they are not statically typed..."lack of type safety and absence of static query checking" "concatenation of strings which is usually very unsafe "

"Criteria Query API ended up very verbose and practically unreadable. "

"jOOQ generates Java code from your database and lets you build type safe SQL queries through its fluent API. "

So this is no ORM framework, it uses your DB as it is, it simply allows you to write safer SQL queries directly in a fluent Java API. No Hocus-Pocus, it's a 1-to-1 mapping between DB and Java.

Here some examples

how to use it and

If you want to use Native SQL or JPQL in Spring:

This is the horribly verbose JPA Criteria API
" the main and most hard-hitting advantage of Criteria queries over HQL is the nice, clean, Object Oriented API."

Apache SSL and ciphersuites

Useful commands and links

openssl ciphers -v

httpd -v
httpd -V

openssl s_client -connect

yum list all
yum install nmap

nmap -p 443 --unprivileged -script ssl-enum-ciphers

SSLCipherSuite HIGH:!aNULL:!MD5

SSLCipherSuite HIGH:!aNULL:!MD5:!SSLv3:!TLSv1

443/tcp open  https
| ssl-enum-ciphers: 
|   SSLv3: No supported ciphers found
|   TLSv1.0: No supported ciphers found
|   TLSv1.1: No supported ciphers found
|   TLSv1.2: 
|     ciphers: 
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - strong
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - strong
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - strong
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - strong
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - strong
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - strong
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - strong
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - strong
|       TLS_RSA_WITH_AES_128_CBC_SHA256 - strong
|       TLS_RSA_WITH_AES_128_GCM_SHA256 - strong
|       TLS_RSA_WITH_AES_256_CBC_SHA256 - strong
|       TLS_RSA_WITH_AES_256_GCM_SHA384 - strong
|     compressors: 
|       NULL
|_  least strength: strongÉvariste_Galois

talking about GCM ciphers

yarn react and materialui

open cmd with admin rights:
choco install yarn
close this cmd and open a "normal" cmd

yarn create react-app app
cd app
yarn add bootstrap@4.1.3 react-cookie@3.0.4 react-router-dom@4.3.1 reactstrap@6.5.0
yarn add @material-ui/core
yarn start

in App.js:

import React, {Component} from 'react';
import './App.css';
import Button from '@material-ui/core/Button';
import Table from '@material-ui/core/Table';
import TableRow from '@material-ui/core/TableRow';
import TableCell from '@material-ui/core/TableCell';

Friday, May 10, 2019

CDI in IntelliJ Java Enterprise projects

I was following this tutorial to deploy a Primefaces application to Wildfly 16, but I kept getting an error

unable to find cdi beanmanager

I have tried adding Maven support and adding the dependency




to no avail.

Funnily, setting webapp version="2.3" instead of version="4.0" in web.xml fixes the problem.

Then I added CDI support as shown here:

and using version="4.0" and things are working.

good old friend JMeter

JMeter is one of those primitive animals that never goes extinct.

Decent presentation:

Excellent comparison with SoapUI

JMeter is good for a VERY quick and dirty PERFORMANCE test of a service.

Incorporating JMeter Performance tests in Maven builds: and this is the plugin

Some books on the topic:

Sai Matam, Jagdeep Jain - Pro Apache JMeter_ Web Application Performance Testing Apress (2017)

Bayo Erinle - JMeter Cookbook Packt Publishing (2014)

Bayo Erinle - Performance Testing with JMeter 3 Enhance the performance of your web application Packt Publishing (2017)

GraalVM native image

download GraalVM CE and unzip it to /home/centos/graalvm-ce-19.0.0/

export JAVA_HOME=/home/centos/graalvm-ce-19.0.0/
export GRAALVM_HOME=/home/centos/graalvm-ce-19.0.0/

cd /home/centos/graalvm-ce-19.0.0/bin
./java -version
sudo ./gu install native-image


public class HelloWorld {
        public static void main(String[] args) {
            System.out.println("hello world");


time ./java HelloWorld

hello world

real 0m0.074s
user 0m0.057s
sys 0m0.019s

./native-image -H:+ReportExceptionStackTraces HelloWorld

Build on Server(pid: 6249, port: 45750)
[helloworld:6249]    classlist:     299.78 ms
[helloworld:6249]        (cap):     359.96 ms
[helloworld:6249]        setup:     479.50 ms
Error: Basic header file missing (). Make sure headers are available on your system.$UserException: Basic header file missing (). Make sure headers are available on your system.
 at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(
 at java.util.concurrent.ForkJoinTask.doExec(
 at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(
 at java.util.concurrent.ForkJoinPool.runWorker(
Error: Image build request failed with exit status 1

sudo yum install glibc-devel
sudo yum install zlib-devel
sudo yum install gcc

./native-image HelloWorld

time ./helloworld
hello world

real 0m0.012s
user 0m0.001s
sys 0m0.011s


Monday, May 6, 2019


This is an excellent book - not only about technology but mostly about culture, leadership, teamwork, innovation.

I don't share the enthusiastic vision of the author for which life is about serving corporations to beat competition and cut jobs. However it's an educational book.

JDK maven Nexus and HTTPS

If your Nexus repository uses certificates signed by your own Root CA, chances are that a JDK doesn't trust them.

Then when you run

mvn package

you get PKIX path building failed:
unable to find valid certification path to requested target

Go to your JAVA_HOME\jre\lib\security folder, where the cacerts file is located, and issue

keytool -list -v -keystore cacerts

enter "changeit" as password

this shold tell you all your trusted CAs

You should import your own CA certificate to into this keystore.

I have tried also setting:

set MAVEN_OPTS="-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true"

but it disn't work for me.

Panache as a wrapper for Hibernate

The product seems very well conceived, it really streamlines your JPA code.

One more aspect where the Java world has completely screwed up, is the 20 different ways you can implement DB queries....
ah if only ORM had been embedded into the language from the beginning, we would be dealing with a single persistence framework.

Thursday, May 2, 2019

Enabling Swagger in a Java EE application

This should be enough:

0) add Maven dependencies:


1) with an Application, register the Swagger jaxrs resources:

import java.util.Set;


public class JaxRsActivator extends Application {

 public Set<Class<?>> getClasses() {
  Set<Class<?>> resources = new java.util.HashSet<>();
//  resources.add(BearerTokenFilter.class);
  return resources;

 private void addRestResourceClasses(Set<Class<?>> resources) {


2) register the Swagger configuration:

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;

import com.wordnik.swagger.config.ConfigFactory;
import com.wordnik.swagger.config.ScannerFactory;
import com.wordnik.swagger.config.SwaggerConfig;
import com.wordnik.swagger.jaxrs.config.DefaultJaxrsScanner;
import com.wordnik.swagger.jaxrs.reader.DefaultJaxrsApiReader;
import com.wordnik.swagger.reader.ClassReaders;

@WebServlet(name = "SwaggerJaxrsConfig", loadOnStartup = 1)
public class SwaggerJaxrsConfig extends HttpServlet {

 public void init(ServletConfig servletConfig) {
  try {
   SwaggerConfig swaggerConfig = new SwaggerConfig();
   ScannerFactory.setScanner(new DefaultJaxrsScanner());
   ClassReaders.setReader(new DefaultJaxrsApiReader());
  } catch (ServletException e) {

3) then you can annotare your services methods:

import javax.inject.Inject;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;

@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Api(value = "/pippo", description = "REST service end-points exposed to Pippo")
public class PippoService {
 @ApiOperation(value = "All Pippos", notes = "List all Pippos")
 @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 500, message = "Server error, check log files") })
 public List listPippobyQuery(
                 @ApiParam(value = "the hostname where Pippo resides") @QueryParam("hostname") String hostName) {

  return listPippo(hostName);

Monday, April 29, 2019

JAXRS client with Jersey

As usual we start from the excellent Baeldung

The working solution is in and the client is in the test directory (Jersey is provided with "test" scope, while the "main" can be built with maven and deployed to WebLogic for instance)

The project is to turn the Service in a set of services with different types of payloads (JSON, XML, binary) and different marshaling/unmarshaling frameworks (Jexson, GSON...) , then run some performance test (using junit5) under different load conditions.

Swagger for Java EE reasteasy or jersey

Making Swagger work in Spring is very easy.

You can use it also in Java EE (Wildfly, WebLogic, even Tomcat!!! )

but all the documentation I have found is a bit outdated:

I have tried APIEE and but it's not showing my services and I see no error.

Some other outdated articles:

I have no time now, but if I need to write REST services in Java EE I would not live without Swagger...

Gradle deploy to Nexus

mkdir /home/centos/gitclones/gradletest
cd /home/centos/gitclones/gradletest
gradle init --type java-application

gradle build

vi build.gradle
add to plugins:
id 'maven'

maven Plugin for Gradle is documented here

gradle install

ls -ltra /home/centos/.m2/repository/gradletest/unspecified/
total 4956
-rw-r--r-- 1 centos docker 2371522 Apr 29 13:23
-rw-r--r-- 1 centos docker 2693120 Apr 29 13:23 gradletest-unspecified.tar
-rw-r--r-- 1 centos docker     752 Apr 29 13:23 gradletest-unspecified.jar
-rw-r--r-- 1 centos docker     756 Apr 29 13:23 gradletest-unspecified.pom

cat /home/centos/.m2/repository/gradletest/unspecified/gradletest-unspecified.pom


group and version are missing!

then you can follow the steps here

you define the group and version in your projects' build.gradle, you define nexus username/password/url in ~/.gradle/ and you use the maven-publish plugin to publish to Nexus

IntelliJ IDEA Essentials

this is a really precious book, very focused and essential, to learn very practical tricks on how to use Intellij effectively

Sunday, April 28, 2019

JPG to PDF conversion in Java

Create a Spring Initializer App (plain vanilla)

add this dependency: com.itextpdf:itextpdf:5.5.13

run this code

package org.pierre.jpgtopdf;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class JpgtopdfApplication implements CommandLineRunner {

    public static void main(String[] args) {, args);

    public void run(String... args) throws Exception {
        File root = new File("D:\\pierre\\tasse2019\\");
        String outputFile = "output.pdf";
        List<String> files = new ArrayList<String>();
        String[] alljpgs = root.list((dir, name) -> name.endsWith("jpg"));

        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(new File(root, outputFile)));;
        for (String f : files) {
            Image image = Image.getInstance(new File(root, f).getAbsolutePath());
            image.setAbsolutePosition(0, 0);

It's amazingly fast!

CDI and javax.transaction.TransactionScoped

I was wondering how TransactionScoped works, and I stumbled upon this wonderful example:

This also is a great explanation on Injected beans

It's so clearly explained that I was deeply impressed by this
Gonçalo Marques. We need more of this stuff. Often people post partial, overcomplicated examples.... Gonçalo instead goes straight to the point.

Tuesday, April 23, 2019

Jenkins enable project based security

Sometimes you share a Jenkins instance amongst several projects (IMHO this is bad practice, each project should have its own Jenkins to minimize interference)

This is how to do it (copied from )

a) make sure Matrix Authorization Strategy Plugin is installed (Manage Jenkins/Manage Plugins/Installed Plugins)

b) "Manage Jenkins", "Configure Global Security", add the target user to the "Project-based Matrix Authorization Strategy ",
add the target user with permissions "Overall/Read and Job/Read"

c) on the main page, select the target project, "Enable project-based security", add the target user and on the right, click on the "grant all permissions" button

at this point the user has login and can administer the target project, but only view other projects.

Jenkins would be a much better tool if all these configuration operations could be easily scriptable. Nowadays it's just a huge clickodrome and very awkward to manage, you have to wade through zillion of configuration pages and unless you are really experienced it's sometimes frustrating ... you don't even have a "search" functionality for configuration options, you have to remember all locations by heart...

Sunday, April 21, 2019

Simple Spring Boot and React working example

Matt Raible is a boss and he is so straight to the point and precise.

Remember that if you have in your pom.xml the dependency spring-boot-starter-security, then Spring Boot will enable security by default with username "user" and a dynamically generated password:

so for the time being I have excluded this dependency.

This should explain more how to handle web security with the great fluent api provided by Spring.

Friday, April 19, 2019

Intellij and WebLogic

Wednesday, April 17, 2019

never copy/paste from outlook or Word

Microsoft sucks

The command on the left was copied from an email (Outlook). And it was failing, returning EVERYTHING, not only config.xml.

Then I have typed all over again (right pane) and it was working

Visually they look absolutely the same, even in Notepad++. But a closer inspection reveals hidden chars.

Copying and pasting from Outlook or Word has caused more victims than the 1919 Spanish Flu.

I remember a production delivery failed because someone copied a command from a Word document where Word had capitalized a property name.


package com.example.demo;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

public class DemoApplication implements CommandLineRunner {

    public static void main(String[] args) {, args);

    public void run(String... args) throws Exception {
        CompletableFuture<String> completableFuture = new CompletableFuture<String>();
        completableFuture.complete("Future's Result");

        String result = completableFuture.get();

        CompletableFuture<Void> future = CompletableFuture.runAsync(new Runnable() {
            public void run() {
                // Simulate a long-running Job
                try {
                } catch (InterruptedException e) {
                    throw new IllegalStateException(e);
                System.out.println("I'll run in a separate thread than the main thread.");
        // Block and wait for the future to complete


Ruminations about Jenkins

The jobs are defined in here:


For every project (item), there is a folder.

In every folder there is a config.xml file which hopefully should contain the entire project definition.

My assumption is that one should simply save the config.xml, and this is enough to recreate the project elsewhere.

I am worried because the Project definitions in Jenkins are not saved in bitbucket,
and we don’t have an automated way to export them from PROD and import them to a UAT instance.

One COULD tar the $JENKINS_HOME/jobs folder, but it’s very bulky.

[jobs]$ cd myproject/

[myproject]$ ls -ltra

drwxr-xr-x. 3 pippo pippogroup 4096 Jul 18 2016 modules
-rw-r--r--. 1 pippo pippogroup 6 Apr 25 2018 nextBuildNumber
lrwxrwxrwx. 1 pippo pippogroup 26 Apr 25 2018 lastSuccessful -> builds/lastSuccessfulBuild
lrwxrwxrwx. 1 pippo pippogroup 22 Apr 25 2018 lastStable -> builds/lastStableBuild
drwxr-xr-x. 5 pippo pippogroup 4096 Apr 25 2018 workspace
drwxr-xr-x. 24 pippo pippogroup 4096 Apr 25 2018 builds
-rw-r--r--. 1 pippo pippogroup 7257 Apr 25 2018 config.xml
drwxr-xr-x. 5 pippo pippogroup 4096 Apr 25 2018 .
drwxr-xr-x. 360 pippo pippogroup 20480 Mar 18 15:06 ..

especially the workspace is a PIG

So for the time being I will simply tar up all the config.xml and untar them in UAT:


find . –maxdepth 2 –name config.xml | tar cvf /var/tmp/alljenkinsconfig.tar –T –

(maxdepth is important to avoid picking up files coming from the workspaces)

However we should really really IMHO push all those config.xml to bitbucket, regularly – ideally automatically whenever someone changes a config.xml:

git init
#set origin and remote
find . –maxdepth 2 –name config.xml –exec git add {} \;
git commit -m "blablabla"
git push

Incidentally, many project folders contain spaces, which makes it much trickier to write scripts to manipulate them.

I am not in favor of Capital Punishment, apart from cases when people create folders containing spaces.

Jenkins sucks anyway. Design is from Napoleonian Era, UI made by a freak, configuration freakishly XML based without fluent Administration Groovy API,
actually in the old times they were much better at designing stuff, think of the Tour Eiffel or the Pyramids and the Coliseum.
Nowadays any idiotic monkey can code freakish products like Maven or Jenkins and become a celebrity.

Thread dumps analysis

this post provides useful insights on how to detect issues from a Thread Dump:

For a quick thread dump consolidation one can use or (both are quite equivalent)....

Problem is that these tools are Application Server agnostic and don't tell you what is normal and what is not. I think some AI should be added to the tool, plus some graphical rendering for instance of the lock analysis.

When I have time I want to look into

Anyway advanced thread analysis is a skill in itself and should be done with proper tooling... manually sorting stuff can be overwhelming for the regular human being.

Saturday, April 13, 2019

Mockito revisited

I have used Mockito in 2010. Then I never did SERIOUS Java development any more (shame on me...)

Yet I strongly believe that a solid implementation of Mocks is the foundation of healthy, fully testable software.
If you can't entirely automate your application tests, you are playing with your life.


source code is here

List mockedList;

List spiedList = new ArrayList();

ArgumentCaptor argCaptor;

I am getting : Illegal reflective access by org.mockito.internal.util.reflection.AccessibilityChanger
Hopefully Mockito folks will fix this one da.

Wednesday, April 10, 2019

Gradle plugin for Jenkins

Maven Sucks, so we welcome Gradle - it can't possibly be worse than Maven!

it seems that Gradle Plugin is installed as part of the "common plugins". I use an old Jenkins 2.138.

export GRADLE_HOME=/home/centos/gradle/gradle-4.8
#make sure $GRADLE_HOME/bin is in $PATH
cd /home/centos/gitclones
git clone
cd gradle-simple/
gradle clean
gradle build
#check if jar was built
ls -ltra build/libs

I configure a freestyle Jenkins item to checkout from Github and "clean build" as gradle tasks...
Then I inspect /home/centos/.jenkins/workspace/gradletest/build/libs/ and the jar has been built there... great!

If I want to copy the plugin to another machine, it's in /home/centos/.jenkins/plugins/gradle.jpi


Manifest-Version: 1.0
Plugin-Dependencies: structs:1.3
Long-Name: Gradle Plugin
Compatible-Since-Version: 1.0
Plugin-Developers: Stefan Wolf:wolfs:
Group-Id: org.jenkins-ci.plugins
Extension-Name: gradle
Plugin-Version: 1.31
Jenkins-Version: 1.651.3
Short-Name: gradle

Tuesday, April 9, 2019

Effective Java third edition

the source code:

*clone (p. 86)
copy constructor/ copy factory
java.util.Comparator.comparingInt + thenComparingInt

immutable objects

composition over inheritance

default methods

generics and collections

unbounded wildcard types (<?>)

PECS producer extends consumer super



Monday, April 8, 2019

Generics and collections

this one has no compilation errors:

Set a;
Set<Object> b;
Set<? super Object> c;

a = new HashSet();
b = new HashSet<>();
c = new HashSet<>();

c = a;
c = b;
b = a;
b = c;
a = c;
a = b;

but if I use

Set<Object> b;
Set<?> c;

then "c = b" gives compilation error

Error:(26, 13) java: incompatible types: java.util.Set cannot be converted to java.util.Set

This is interesting, since ? means "any Object and subclasses"... while "? super Object" means "Object and its superclasses"
but Object has no superclasses, so effectively it's only Object.

If I use:
b = new HashSet<>();
Set<?? extends Object> c;

b = c;
fails with the same error:

Error:(26, 13) java: incompatible types: java.util.Set cannot be converted to java.util.Set

The raw type a can be assigned all the time to all the others.

similarly, collections are INVARIANT:
Set<Number> numset = new HashSet<>();
Set<Integer> intset = new HashSet<>();
Set<?> allset = new HashSet<>();

numset = intset; // INVALID
intset = numset; // INVALID
allset = numset; // VALID
numset = allset; // INVALID

but arrays are COVARIANT:

Number[] numarr = new Number[1];
Integer[] intarr = new Integer[1];
numarr = intarr; // VALID
intarr = numarr; // INVALID

Sunday, April 7, 2019

Amazing brushes by Reto

a colleague of mine, Reto, is a passionate photographer and Photoshop artist , here some links to his creations:

Intellij , maven and the source or target java language level

I create a new Java "maven" project, set it to Java 12 (ctrl-alt-shift-S, MOdules, Language level), but when I build I get:

"Warning:java: source value 1.5 is obsolete and will be removed in a future release"

Apparently this is due to the prehistoric, nonsensical Maven Compiler Plugin using Java 1.5 by default

you can either insert in the pom.xml :




Remember also to make sure that ctrl-alt-S (Settings) Settings -> Build, Execution, Deployment -> Build Tools -> Maven -> Importing is set to use JDK 12. So complicated. So brittle. So Maven.

Working with Maven is like traveling back to prehistoric times, like the Mural de la Prehistoria in Cuba,

developers on the right about to be eaten by Maven on the left

Priceless String manipulation Intellij plugin

ctrl-alt-S, then "Plugins" search for "String Manipulations"; install and reboot.

for instance, if you need to "escape XML" (that is transform reserve chars in "% bla ;" sequences :

File/new scratch file (or ctrl-alt-shift-ins), paste your XML, select all, right click "String manipulation", "escape xml"

Normally I used Notepad++ and the "XML Tools Plugin", but this seems more useful.

Wednesday, April 3, 2019

git synchronize repositories

It happens that an external Git repository has to be mirrored internally in a corporate git repository. This cloning and mirroring should include branches, tags, commit history etc. and be one-way (internal changes are lot upon synchronization)

Luckily you don't have to write special scripts, all is provided by git:

Let's make an experiment

in github I create a "gitclonesource" and a "gitclonedestination" empty repositories

mkdir gitclonetests
cd gitclonetests

#let's prepare the source
mkdir gitclonesource
cd gitclonesource
git init
echo "ciao" >
git add
git commit -m "first commit"
git remote add origin
git push -u origin master

#create branch
git checkout -b mybranch
echo "hello" >> mybranch.txt
git add mybranch.txt
git commit -am "added mybranch.txt"
git push --set-upstream origin mybranch

#create tag
git checkout master
git tag -a v1.4 -m "my version 1.4"
git push --tags

#now clone source and push to destination with all branches and tags
cd ..
#this will create a folder gitclonesource.git
git clone --bare
#when you cd, you will see a message BARE:master if using Git bash
cd gitclonesource.git/
git push --mirror

Counting objects: 7, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (7/7), 600 bytes | 200.00 KiB/s, done.
Total 7 (delta 0), reused 0 (delta 0)
 * [new branch]      master -> master
 * [new branch]      mybranch -> mybranch
 * [new tag]         v1.4 -> v1.4

and, lo and behold, in the gitclonedestination I can find my branch and the tag! All cloned in one go!

at this point you can cleanup the gitclonedestination.git:

cd ..
rm -rf gitclonedestination.git

Monday, April 1, 2019

WebLogic Security documentation JACC "Java Authorization Contract for Containers" java.lang.SecurityManager

Java Authentication Service Provider Interface for Containers (JASPIC)

Training Material:

Old book

Best Spring books

reblogging for my own reference, I am planning to read all those 5 books...

- Spring in Action 5
- Cloud Native Java
- Learning Spring Boot 2.0
- Spring 5 Recipes
- Spring Microservices in Action

I am already going through but I find it incredibly non-concise - lot of repeated stuff, very lengthy and boring coding sessions where you don't really see much new, lot of unnecessary verbosity. Not my style, I like crisp, focused, simple examples and just fundamental facts and concepts.

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.

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

Thursday, February 28, 2019

CKA Certification (Kubernetes Administrator) here the topics to be covered

I would start by reading the official doc

Kubernetes Master : kube-apiserver, kube-controller-manager and kube-scheduler

Non-master node : kubelet, kube-proxy

Control Plane , kubectl,

etcd, kube-scheduler, kube-controller-manager

PodSpecs , Cluster DNS ,

(to be continued)

Monday, February 25, 2019

Viktor Farcic and Jenkins-X

The ebook is available to read for free - the first 60 pages.

For a good overall presentation of JenkinsX

az CLI for Azure Kubernetes Services (AKS)

I am installing AZ on Windows. At the end of installation, I reboot (maybe not needed...)

az login -> this opens a browser window which automatically logs you in your AKS account

in return , you get a JSON with your account details. Nice.

"cloudName": "AzureCloud",
"id": "9ab0d5c-036-495-b6d-25b05be758",
"isDefault": true,
"name": "Free Trial",
"state": "Enabled",
"tenantId": "9dc2b0-897-4b6-adf1-8c5488ea413",
"user": {
"name": "",
"type": "user"

which can be obtained also by doing

az account show

I am stingy, so I first check my billing:

az billing invoice list

NotOptedIn - You are not allowed to download invoices. Please contact your account administrator ( to turn on access in the management portal for allowing to download invoices through the API.

So I log into

Be very careful not to use the Azure Cloud Shell available in the Browser UI... using it will create a Storage Account to host a shared drive needed by the Shell, and this will reduce to 1 month the (otherwise 1 year) trial account. So, just install the AZ cli on your machine and be happy.

To display a Resource Group (RG):
az group show --name myResourceGroup

To create a RG
az group create --name myResourceGroup --location "East US"

Saturday, February 2, 2019

JenkinsX and GKE on Centos

Install JX:

mkdir -p ~/.jx/bin

curl -L \
    | tar xzv -C ~/.jx/bin

export PATH=$PATH:~/.jx/bin

echo 'export PATH=$PATH:~/.jx/bin' \
>> ~/.bashrc

install gcloud:

tee -a /etc/yum.repos.d/google-cloud-sdk.repo << EOM
name=Google Cloud SDK

yum install google-cloud-sdk

create GKE cluster
jx create cluster gke
(this will install kubectl and try to install helm.... helm installation fails with
"error: error installing helm: failed to remove helm secrets: failed to run '/root/.jx/bin/helm plugin remove secrets' command in directory '', output: 'Error: Plugin: secrets not found': exit status 1"

So I download help here
gunzip helm-v2.12.3-linux-amd64.tar.gz tar xvf helm-v2.12.3-linux-amd64.tar mv linux-amd64/helm /usr/local/bin/helm mv linux-amd64/tiller /usr/local/bin/tiller
I request an authorization code at
then run
gcloud auth login --brief
and paste the authorization code
jx install --provider=gke unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined error: failed to create the kube client: unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined
I do:
then again "jx install --provider=gke" and I get
open /var/run/secrets/ no such file or directory error: failed to create the kube client: open /var/run/secrets/ no such file or directory
and of course also this fails
jx create cluster gke -n jx-rocks -p pippo -z us-east1-b -m n1-standard-2 --min-num-nodes 3 --max-num-nodes 5 --default-admin-password admin --default-environment-prefix jx-rocks
with this error
open /var/run/secrets/ no such file or directory
Go to the following link in your browser:

ERROR: There was a problem with web authentication.
ERROR: (gcloud.auth.login) EOF when reading a line
Enter verification code: Error: Command failed  gcloud auth login --brief
error creating cluster exit status 1
error: exit status 1

I have googled everywhere and I find no help... it seems that JX is still a niche product and immature..
I am giving up...
Maybe I will try some parameters
kubectl get ns The connection to the server localhost:8080 was refused - did you specify the right host or port?

Wednesday, January 23, 2019

Minikube on Centos

I want to have a "mini" version of Kubernetes on my Centos laptop.

I would prefer not to install an Hypervisor, since k8s can use "--vm-driver=none"...
but I give it a try to install VirtualBox

After installing VirtualBox, I can proceed with minikube

curl -Lo minikube \
&& chmod +x minikube

sudo cp minikube /usr/local/bin && rm minikube

minikube version
minikube version: v0.33.1

minikube start

I get "Error parsing version semver: Version string empty"

kubectl cluster-info
kubectl get nodes

I can try also with "minikube start --vm-driver=none", which however requires docker

Saturday, January 19, 2019

Coding and cooking


Friday, January 18, 2019

Running Centos on Windows

once you have upgraded to Windows PRO, you can install Docker for Windows

Then open your Git Bash shell and run:

winpty docker run --name centos -i -t -d centos

If the container is stopped, you can simply

docker start centos

and login again:

winpty docker exec -ti centos bash

So you can have a "REAL" Centos on Windows... cool...

VirtualBox and Hyper-V on Windows 10 PRO

I have recently installed Windows PRO. During installation of Hyper-V, it duly warns you that you will no longer be able to use VirtualBox. Which is true, because when I start a VM in VirtualBOx I get the message:

WHvCapabilityCodeHypervisorPresent is FALSE! Make sure you have enabled the 'Windows Hypervisor Platform' feature. (VERR_NEM_NOT_AVAILABLE).
VT-x is not available (VERR_VMX_NO_VMX).

Apparently all you need to do to re-enable VirtualBox is:

open CMD as Administrator
bcdedit /set hypervisorlaunchtype off

reboot your machine

To restore Hyper-V you simply run:
bcdedit /set hypervisorlaunchtype on
bcdedit /set hypervisorlaunchtype auto

I haven't tested yet but it should work IMHO

bcdedit is this

Windows Boot Manager
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume2
path                    \EFI\Microsoft\Boot\bootmgfw.efi
description             Windows Boot Manager
locale                  fr-FR
inherit                 {globalsettings}
badmemoryaccess         Yes
default                 {current}
resumeobject            {b32f6aed-59a4-11e8-b3f7-b9390bbf0244}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Windows Boot Loader
identifier              {current}
device                  partition=C:
path                    \WINDOWS\system32\winload.efi
description             Windows 10
locale                  fr-FR
inherit                 {bootloadersettings}
recoverysequence        {b32f6aef-59a4-11e8-b3f7-b9390bbf0244}
displaymessageoverride  Recovery
recoveryenabled         Yes
badmemoryaccess         Yes
isolatedcontext         Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \WINDOWS
resumeobject            {b32f6aed-59a4-11e8-b3f7-b9390bbf0244}
nx                      OptIn
bootmenupolicy          Standard
hypervisorlaunchtype    Auto