Sunday, December 30, 2018

Swagger getting started

At first I tried to go to , generate the Maven project to generate a RestEasy-EAP server, build and deploy to Wildfly 12.

There I got this error:

ERROR [] (Controller Boot Thread) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "swagger-jaxrs-resteasy-eap-server-1.0.0.war")]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => [
"WFLYCTL0180: Services with missing/unavailable dependencies" => [
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService is missing [\"swagger-jaxrs-resteasy-eap-server-1.0.0\".\"swagger-jaxrs-resteasy-eap-server-1.0.0\".DefaultDataSource]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.undertow.deployment.default-server.default-host./v2 is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START]",
"\"swagger-jaxrs-resteasy-eap-server-1.0.0\".\"swagger-jaxrs-resteasy-eap-server-1.0.0\".DefaultDataSource is missing []",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".deploymentCompleteService is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START, jboss.undertow.deployment.default-server.default-host./v2, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START]"

and the deployment fails. I felt discouraged and I turned to something simpler.

First I will implement my own Rest Service:

then I run as http://localhost:8080/greeting

Then I move to adding Swagger to thie REST webapp
I add the SwaggerConfig class with the @EnableSwagger2

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

public class SwaggerConfig {                                    
    public Docket api() { 
        return new Docket(DocumentationType.SWAGGER_2)  

Here I see something comforting

s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/greeting]}" onto public org.springframework.gsrestservice.Greeting org.springframework.gsrestservice.GreetingController.greeting(java.lang.String)
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/swagger-resources/configuration/ui]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.UiConfiguration> springfox.documentation.swagger.web.ApiResourceController.uiConfiguration()
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/swagger-resources]}" onto public org.springframework.http.ResponseEntity<java.util.List<springfox.documentation.swagger.web.SwaggerResource>> springfox.documentation.swagger.web.ApiResourceController.swaggerResources()
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/swagger-resources/configuration/security]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.SecurityConfiguration> springfox.documentation.swagger.web.ApiResourceController.securityConfiguration()
pertySourcedRequestMappingHandlerMapping : Mapped URL path [/v2/api-docs] onto method [public

so now the endpoints are:






Then I add the io.springfox:springfox-swagger-ui:2.9.2 dependency

and I get the Swagger-UI at http://localhost:8080/swagger-ui.html

My code is available here

The Baeldung code is here

Monday, December 24, 2018

Maven Artifact Resolver

add dependency org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-depchain:3.1.3 (default scope, not test scope)

package org.pierre.artifactresolver;


import org.jboss.shrinkwrap.resolver.api.maven.Maven;

public class App 
    public static void main( String[] args )
        System.out.println( "Hello World!" );
        File[] files = Maven.resolver().resolve("org.apache.commons:commons-lang3:3.8.1").withTransitivity().asFile();
        for (File file : files) {

this prints:

Hello World!

Friday, December 14, 2018

Cleaning up old releases in Nexus 2 and 3

In Nexus 2 there is the task "remove releases from repository", where you can further refine the scope by specifying a "repository target" (=a filter).... problem is, the only option you have is the number of the most recent versions to retain.... there is no way to specify "delete all versions older than 2 years, but in any case keep the last 10".

I have written this Spring Boot utility to generate curl commands to delete artifacts based on multiple selection criteria. But it doesn't handle parent pom, which is a limitation.

Also, be aware that the curl command to delete a component, like

curl -u admin:admin123 -X "DELETE" -w "%{http_code}" http://localhost:8281/nexus/service/local/repositories/central/content/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7

every time rebuilds the index, which is very CPU intensive. There is no way to batch multiple deletes in a single transaction.

In Nexus 3

Monday, December 10, 2018

Docker broken after upgrade

sudo systemctl start docker
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.

sudo journalctl -xe

Error starting daemon: error initializing graphdriver: /var/lib/docker contains several valid graphdrivers: devicemapper, overlay2; Please cleanup or explicit

sudo vi /etc/docker/daemon.json

append this at the end and before the closed curly brace:

,"storage-driver": "devicemapper"

sudo systemctl reset-failed docker.service
sudo systemctl start docker.service

Thursday, November 29, 2018

Nexus repo validates Docker images on

In Nexus logs I find a lot of calls to

2018-11-05 14:13:43,416+0100 DEBUG [qtp72695066-56] ADV - > GET /registry-v2/docker/registry/v2/blobs/sha256/4f/4fe2ade4980c2dda4fc95858ebb981489baec8c1e4bd282ab1c3560be8ff9bde/data?verify=1541426623-n%2BHbbRXN3Rr4k6Bxofrsv6tRVFw%3D HTTP/1.1
2018-11-05 14:13:43,416+0100 DEBUG [qtp72695066-56] ADV - Connection request: [route: {tls}->http://ourproxy:8080->][total kept alive: 1; route allocated: 0 of 20; total allocated: 3 of 200]
2018-11-05 14:13:43,417+0100 DEBUG [qtp72695066-56] ADV - Connection leased: [id: 18][route: {tls}->http://ourproxy:8080->][total kept alive: 1; route allocated: 1 of 20; total allocated: 4 of 200]
2018-11-05 14:13:43,475+0100 DEBUG [qtp72695066-4467] ADV - < HTTP/1.1 200 OK @ 129.8 ms 2018-11-05 14:13:43,475+0100 DEBUG [qtp72695066-4467] ADV - Response: HttpResponseProxy{HTTP/1.1 200 OK [Content-Type: application/json, Date: Mon, 05 Nov 2018 13:13:43 GMT, Transfer-Encoding: chunked, Strict-Transport-Security: max-age=31536000, Connection: Keep-Alive] ResponseEntityProxy{[Content-Type: application/json,Chunked: true]}}

we access internet via a Proxy Server ourproxy, which doesn't whitelist

each of them creates a file in $NEXUS_DATA/tmp/docker-content-validation-failures with an "access denied" message from ourproxy

Here they say we should also whitelist

I have no idea if the "docker pull" will fail, or if this "validation" can be disabled...

See also

Nexus repository location of license

If you move your Nexus repository to a new machine, it's quite annoying to have to reinstall the license file.

The trick is to clone the folder ~/.java/.userPrefs, specifically the license is embedded in


and it's common for Nexus2 and Nexus3

I had searched everywhere for a .lic file, to no avail of course.

This is also documented here

java showSettings

This is a priceless feature to display all the settings of the JVM, together with -XX:+PrintCommandLineFlags it can show a world of hidden stuff.

java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=261069952 -XX:MaxHeapSize=4177119232 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)

java -XshowSettings:all -version

VM settings:
    Max. Heap Size (Estimated): 3.46G
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

Property settings:
    awt.toolkit = sun.awt.X11.XToolkit
    file.encoding = UTF-8
    file.encoding.pkg =
    file.separator = /
    java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
    java.awt.printerjob = sun.print.PSPrinterJob
    java.class.path = .
    java.class.version = 52.0
    java.endorsed.dirs = /usr/lib/jvm/java-1.8.0-openjdk-
    java.ext.dirs = /usr/lib/jvm/java-1.8.0-openjdk-
    java.home = /usr/lib/jvm/java-1.8.0-openjdk- = /tmp
    java.library.path = /usr/java/packages/lib/amd64
        /usr/lib = OpenJDK Runtime Environment
    java.runtime.version = 1.8.0_191-b12 = Java Platform API Specification
    java.specification.vendor = Oracle Corporation
    java.specification.version = 1.8
    java.vendor = Oracle Corporation
    java.vendor.url =
    java.vendor.url.bug =
    java.version = 1.8.0_191 = mixed mode = OpenJDK 64-Bit Server VM = Java Virtual Machine Specification
    java.vm.specification.vendor = Oracle Corporation
    java.vm.specification.version = 1.8
    java.vm.vendor = Oracle Corporation
    java.vm.version = 25.191-b12
    line.separator = \n 
    os.arch = amd64 = Linux
    os.version = 2.6.32-754.el6.x86_64
    path.separator = : = 64
    sun.boot.class.path = /usr/lib/jvm/java-1.8.0-openjdk-
    sun.boot.library.path = /usr/lib/jvm/java-1.8.0-openjdk-
    sun.cpu.endian = little
    sun.cpu.isalist = = UnicodeLittle = SUN_STANDARD
    sun.jnu.encoding = UTF-8 = HotSpot 64-Bit Tiered Compilers
    sun.os.patch.level = unknown = US
    user.dir = /root
    user.home = /root
    user.language = en = root
    user.timezone = 

Locale settings:
    default locale = English
    default display locale = English (United States)
    default format locale = English (United States)
    available locales = , ar, ar_AE, ar_BH, ar_DZ, ar_EG, ar_IQ, ar_JO, 
        ar_KW, ar_LB, ar_LY, ar_MA, ar_OM, ar_QA, ar_SA, ar_SD, 
        ar_SY, ar_TN, ar_YE, be, be_BY, bg, bg_BG, ca, 
        ca_ES, cs, cs_CZ, da, da_DK, de, de_AT, de_CH, 
        de_DE, de_GR, de_LU, el, el_CY, el_GR, en, en_AU, 
        en_CA, en_GB, en_IE, en_IN, en_MT, en_NZ, en_PH, en_SG, 
        en_US, en_ZA, es, es_AR, es_BO, es_CL, es_CO, es_CR, 
        es_CU, es_DO, es_EC, es_ES, es_GT, es_HN, es_MX, es_NI, 
        es_PA, es_PE, es_PR, es_PY, es_SV, es_US, es_UY, es_VE, 
        et, et_EE, fi, fi_FI, fr, fr_BE, fr_CA, fr_CH, 
        fr_FR, fr_LU, ga, ga_IE, hi, hi_IN, hr, hr_HR, 
        hu, hu_HU, in, in_ID, is, is_IS, it, it_CH, 
        it_IT, iw, iw_IL, ja, ja_JP, ja_JP_JP_#u-ca-japanese, ko, ko_KR, 
        lt, lt_LT, lv, lv_LV, mk, mk_MK, ms, ms_MY, 
        mt, mt_MT, nl, nl_BE, nl_NL, no, no_NO, no_NO_NY, 
        pl, pl_PL, pt, pt_BR, pt_PT, ro, ro_RO, ru, 
        ru_RU, sk, sk_SK, sl, sl_SI, sq, sq_AL, sr, 
        sr_BA, sr_BA_#Latn, sr_CS, sr_ME, sr_ME_#Latn, sr_RS, sr_RS_#Latn, sr__#Latn, 
        sv, sv_SE, th, th_TH, th_TH_TH_#u-nu-thai, tr, tr_TR, uk, 
        uk_UA, vi, vi_VN, zh, zh_CN, zh_HK, zh_SG, zh_TW
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)

Monday, November 26, 2018

Java and JGit

The Jgit library makes it REALLY easy to work with Git repositories.

Just create a basic Spring boot application, add dependency


and use this code

package com.example.jgittest;


import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Repository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

public class JgittestApplication  implements CommandLineRunner {

 public static void main(String[] args) {, args);
 public void run(String... args) throws Exception {
  File directory1 = new File("c:\\temp\\one");
  Git git1 = Git.init().setDirectory(directory1).call();
  File newFile = new File(directory1, "pippo.txt");
  PrintWriter out = new PrintWriter(newFile);
  out.println("hello pippo");
  Repository rep1 = git1.getRepository();
  AddCommand add = git1.add();
  System.out.println("adding pippo.txt");;
  CommitCommand commit = git1.commit();
  System.out.println("committing pippo.txt");
  commit.setMessage("initial commit").call();
  File directory2 = new File("c:\\temp\\two");
  if (!directory2.exists()) {
   Git git2 = Git.cloneRepository().setURI("").setDirectory(directory2).call();

Saturday, November 24, 2018

Velocity and rendering JSONObjects or Java Beans

You can use a Velocity template to render either a JsonNode or its corresponding Java bean,
without changing the velocity template.

Code is available here (the .wm file location is hardcoded with a Widows machine, sorry!)

and the full code is visible here

BEWARE the velocity template is stored under the resources folder

The only funny thing is that in the JsonNode the values retain the ""

Wednesday, November 14, 2018

Jboss CLI, change individual attributes of a security domain without having to remove and add the domain from scratch

Jboss CLI, change individual attributes of a security domain without having to remove and add the domain from scratch

If you need for instance to update the baseFilter of the AdvancedAdLdap module:

In the custom cli, execute this command:


and the baseFilter is updated:

<security-domain name="SPNEGO" cache-type="default">
  <login-module code="SPNEGO" flag="requisite">
   <module-option name="password-stacking" value="useFirstPass"/>
   <module-option name="serverSecurityDomain" value="host"/>
  <login-module code="AdvancedAdLdap" flag="required">
   <module-option name="password-stacking" value="useFirstPass"/>
   <module-option name="bindDN" value="BLA"/>
   <module-option name="bindCredential" value="BLA"/>
   <module-option name="java.naming.provider.url" value="BLA"/>
   <module-option name="baseCtxDN" value="BLA"/>
   <module-option name="baseFilter" value="(sAMAccountName={0})"/>
   <module-option name="roleAttributeID" value="memberOf"/>
   <module-option name="rolesCtxDN" value="BLA"/>
   <module-option name="roleAttributeIsDN" value="true"/>
   <module-option name="roleNameAttributeID" value="cn"/>
   <module-option name="searchScope" value="SUBTREE_SCOPE"/>
   <module-option name="recurseRoles" value="true"/>
  <login-module code="" flag="optional">
   <module-option name="rolesProperties" value="${jboss.server.config.dir}/bla-war/"/>
   <module-option name="replaceRole" value="false"/>

Tuesday, November 6, 2018

Centos 7 gnome-shell high CPU on VirtualBox

top shows very high CPU usage. and UI is very very slow.

googling around, they say it's probably doing "software" rendering. it makes sense because CPU goes higher when I move something on the screen

in /var/log/Xorg.0.log I find this:

(EE) Failed to load module "vboxvideo" (module does not exist, 0)
(II) AIGLX: Screen 0 is not DRI2 capable
(EE) AIGLX: reverting to software rendering

To investigate, I run
sudo glxinfo
sudo lshw -C video
sudo yum list | grep libnvidia
sudo yum list | grep libegl

the output of glxinfo is

name of display: :0
display: :0  screen: 0
direct rendering: Yes
server glx vendor string: Chromium
server glx version string: 1.3 Chromium
server glx extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, 
    GLX_EXT_texture_from_pixmap, GLX_SGIX_fbconfig
client glx vendor string: Chromium
client glx version string: 1.3 Chromium
client glx extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, 
    GLX_EXT_texture_from_pixmap, GLX_SGIX_fbconfig
GLX version: 1.3
GLX extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, 
    GLX_EXT_texture_from_pixmap, GLX_SGIX_fbconfig
OpenGL vendor string: Humper
OpenGL renderer string: Chromium
OpenGL version string: 2.1 Chromium 1.9
OpenGL shading language version string: 4.30 - Build
OpenGL extensions:
    GL_ARB_depth_texture, GL_ARB_draw_buffers, GL_ARB_fragment_program, 
    GL_ARB_fragment_shader, GL_ARB_multisample, GL_ARB_multitexture, 
    GL_ARB_occlusion_query, GL_ARB_pixel_buffer_object, 
    GL_ARB_point_parameters, GL_ARB_point_sprite, GL_ARB_shader_objects, 
    GL_ARB_shading_language_100, GL_ARB_shadow, GL_ARB_texture_border_clamp, 
    GL_ARB_texture_compression, GL_ARB_texture_cube_map, 
    GL_ARB_texture_env_add, GL_ARB_texture_env_combine, 
    GL_ARB_texture_env_crossbar, GL_ARB_texture_env_dot3, 
    GL_ARB_texture_float, GL_ARB_texture_mirrored_repeat, 
    GL_ARB_texture_non_power_of_two, GL_ARB_texture_rectangle, 
    GL_ARB_transpose_matrix, GL_ARB_vertex_buffer_object, 
    GL_ARB_vertex_program, GL_ARB_vertex_shader, GL_ARB_window_pos, 
    GL_CR_bounding_box, GL_CR_cursor_position, GL_CR_head_spu_name, 
    GL_CR_performance_info, GL_CR_print_string, GL_CR_readback_barrier_size, 
    GL_CR_saveframe, GL_CR_server_id_sharing, GL_CR_server_matrix, 
    GL_CR_state_parameter, GL_CR_synchronization, GL_CR_tile_info, 
    GL_CR_tilesort_info, GL_CR_window_size, GL_EXT_blend_color, 
    GL_EXT_blend_equation_separate, GL_EXT_blend_func_separate, 
    GL_EXT_blend_minmax, GL_EXT_blend_subtract, GL_EXT_clip_volume_hint, 
    GL_EXT_compiled_vertex_array, GL_EXT_draw_range_elements, 
    GL_EXT_fog_coord, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_object, 
    GL_EXT_multi_draw_arrays, GL_EXT_secondary_color, GL_EXT_shadow_funcs, 
    GL_EXT_stencil_two_side, GL_EXT_stencil_two_side, GL_EXT_stencil_wrap, 
    GL_EXT_texture3D, GL_EXT_texture_compression_s3tc, 
    GL_EXT_texture_edge_clamp, GL_EXT_texture_env_add, 
    GL_EXT_texture_env_combine, GL_EXT_texture_filter_anisotropic, 
    GL_EXT_texture_lod_bias, GL_EXT_texture_rectangle, GL_EXT_texture_sRGB, 
    GL_IBM_texture_mirrored_repeat, GL_NV_texgen_reflection, 
    GL_SGIS_generate_mipmap, GL_SGIS_texture_edge_clamp

1 GLX Visuals
    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
0x021 24 tc  0  32  0 r  y y   8  8  8  8 .  .  0 24  8 16 16 16 16  0 0 None

1 GLXFBConfigs:
    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
0x021 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  1 1 None

On VirtualBox, 3D acceleration is enabled.

So far no clue... the world of Linux Video drivers is amazingly complex... too complex for a simple human like me...

Monday, November 5, 2018

Message Digest Performance

If I use the dependency groupId=commons-codec artifactId=commons-codec I get a huge performance hit on the method:[], int)

the code is:

import org.apache.commons.codec.digest.DigestUtils;

FileInputStream fis = new FileInputStream(file);
String md5 = DigestUtils.md5Hex(fis);

If I use sha2

Thursday, November 1, 2018

Spring Shell is very cool

If you are fed up with UI-oriented applications (like, say, Messus (a.k.a. Nexus) ) you can always try to embed a Spring-powered shell, so as to have a powerful scripting cli.

Just follow this example

and in a few clicks you have a functional shell.

BEWARE: baeldung has an example, but it's based on the old API. You will search in vain for Bootstrap class under org/springframework/shell


Sunday, October 28, 2018

Hammering Nexus 3.14

first, create an entry in your settings.xml for mvn to be able to authenticate in nexus


then write this script:


cd $NEXUSHOME/nexus-3.14.0-04/bin

for i in `seq 1 1000`;
 echo "Iteration number " $i
 #make sure nexus is not running before you start it
 ./nexus stop
 ./nexus start
 while [ ! -f $NEXUSLOG ] ;
  sleep 2
 echo "logfile found"
 tail -f $NEXUSLOG | while read LOGLINE
  [[ "$LOGLINE" == *"Started Sonatype Nexus OSS 3.14.0-04"* ]] && pkill -P $$ tail
 #now that it's up, let's wait for some time
 echo "nexus started"
 NEXUSPID=`ps -e -o pid,command | grep | grep -v grep | awk '{print $1}'`
 #wait for a random time before we kill
 sleep $[ ( $RANDOM % 100 )  + 10 ]
 ps -ef | grep nexus
 echo killing $NEXUSPID
 kill -9 $NEXUSPID

and here the 2 scripts to upload continuously stuff to nexus


curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.pom
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.md5
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.pom.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.pom.md5
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar.md5

mvn deploy:deploy-file -DgroupId=commons-beanutils -DartifactId=commons-beanutils -Dversion=1.9.2 -DgeneratePom=true -Dpackaging=jar -DrepositoryId=nexus -Durl=http://localhost:8081/repository/maven-releases -Dfile=$NEXUSHOME/nexus-3.14.0-04/system/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar


curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.pom
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.jar
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.md5
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.pom.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.pom.md5
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.jar.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.jar.md5

mvn deploy:deploy-file -DgroupId=commons-codec -DartifactId=commons-codec -Dversion=1.10 -DgeneratePom=true -Dpackaging=jar -DrepositoryId=nexus -Durl=http://localhost:8081/repository/maven-releases -Dfile=$NEXUSHOME/nexus-3.14.0-04/system/commons-codec/commons-codec/1.10/commons-codec-1.10.jar (this will create always new jars)

for i in `seq 1 1000000`;
 mvn deploy:deploy-file -DgroupId=commons-beanutils -DartifactId=commons-beanutils -Dversion=1.10.${i} -DgeneratePom=true -Dpackaging=jar -DrepositoryId=nexus -Durl=http://localhost:8081/repository/maven-releases -Dfile=$NEXUSHOME/nexus-3.14.0-04/system/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar

 sleep 2

nohup ./ > ./testnexusupload1.log 2>&1 &
nohup ./ > ./testnexusupload2.log 2>&1 &
nohup ./ > ./testnexusupload3.log 2>&1 &


setsid ./ > ./testnexusupload1.log 2>&1 &
setsid ./ > ./testnexusupload2.log 2>&1 &
setsid ./ > ./testnexusupload3.log 2>&1 &

This way with a continuous cycle of restarts I can test the stability of the repository.
If the DB or shards are corrupted we will find out...

In fact, after some iteration I keep getting this error at startup:

2018-10-28 19:04:49,571+0100 INFO [elasticsearch[C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4][clusterService#updateTask][T#1]] *SYSTEM org.elasticsearch.cluster.metadata - [C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4] [2e9a1e67e8a325bcd6ee9f6790ff6c769e791d56] creating index, cause [api], templates [], shards [1]/[0], mappings [component]
2018-10-28 19:04:49,955+0100 INFO [elasticsearch[C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4][clusterService#updateTask][T#1]] *SYSTEM org.elasticsearch.cluster.routing.allocation - [C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4] Cluster health status changed from [RED] to [GREEN] (reason: [shards started [[2e9a1e67e8a325bcd6ee9f6790ff6c769e791d56][0]] ...]).
2018-10-28 19:04:50,065+0100 INFO [quartz-2-thread-1] *SYSTEM - Rebuilding index of repository maven-central
2018-10-28 19:04:50,501+0100 INFO [elasticsearch[C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4][clusterService#updateTask][T#1]] *SYSTEM org.elasticsearch.cluster.metadata - [C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4] [73ae44bc066b6a7a33b4435641d8229b9b66495a] creating index, cause [api], templates [], shards [1]/[0], mappings [component]
2018-10-28 19:04:50,943+0100 ERROR [Thread-44 <command> from component where bucket = :bucket</command>] *SYSTEM - Exception `32DA9B7B` in storage `plocal:/home/centos/nexus314/sonatype-work/nexus3/db/component`: 2.2.36 (build d3beb772c02098ceaea89779a7afd4b7305d3788, branch 2.2.x)
com.orientechnologies.orient.core.exception.OCommandExecutionException: Error on execution of command: from component where bucket = :bucket
DB name="component"
at com.orientechnologies.orient.core.query.OQueryAbstract.execute(
at com.orientechnologies.orient.core.sql.query.OSQLNonBlockingQuery$
Caused by: java.lang.NullPointerException: null
at com.orientechnologies.orient.core.serialization.serializer.binary.impl.index.OCompositeKeySerializer.deserializeFromByteBufferObject(
at com.orientechnologies.orient.core.serialization.serializer.binary.impl.index.OCompositeKeySerializer.deserializeFromByteBufferObject(
at com.orientechnologies.orient.core.index.sbtree.local.OSBTreeBucket.getKey(
at com.orientechnologies.orient.core.index.sbtree.local.OSBTreeBucket.find(
at com.orientechnologies.orient.core.index.sbtree.local.OSBTree.findBucket(
at com.orientechnologies.orient.core.index.sbtree.local.OSBTree.access$2800(
at com.orientechnologies.orient.core.index.sbtree.local.OSBTree$
at com.orientechnologies.orient.core.index.engine.OSBTreeIndexEngine$OSBTreeIndexCursor.nextEntry(
at com.orientechnologies.orient.core.index.OIndexAbstractCursor.hasNext(
at com.orientechnologies.orient.core.index.OIndexChangesWrapper.hasNext(
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.serialIterator(
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.fetchFromTarget(
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.fetchValuesFromIndexCursor(
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.searchForIndexes(
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.searchInClasses(
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLResultsetAbstract.assignTarget(
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.assignTarget(
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.executeSearch(
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.execute(
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLDelegate.execute(
... 6 common frames omitted

This seems a known issue with a workaround/solution

java -jar ./nexus-3.14.0-04/lib/support/nexus-orient-console.jar

connect plocal:/home/centos/nexus314/sonatype-work/nexus3/db/component/ admin admin

Disconnecting from the database [null]...OK
Connecting to database [plocal:/home/centos/nexus314/sonatype-work/nexus3/db/component/] with user 'admin'...
2018-10-28 23:42:11:147 WARNI {db=component} Storage 'component' was not closed properly. Will try to recover from write ahead log... [OLocalPaginatedStorage]
2018-10-28 23:42:11:192 WARNI {db=component} Record{lsn=LSN{segment=105, position=52}} will be skipped during data restore [OLocalPaginatedStorage]
2018-10-28 23:42:11:247 WARNI {db=component} Record OFuzzyCheckpointStartRecord{lsn=LSN{segment=105, position=59}}{lsn=null, previousCheckpoint=LSN{segment=105, position=28}} will be skipped during data restore [OLocalPaginatedStorage]
2018-10-28 23:42:11:248 WARNI {db=component} Record{lsn=LSN{segment=105, position=99}} will be skipped during data restore [OLocalPaginatedStorage]OK

repair database --fix-links

Repairing database...
- Removing broken links...
-- Done! Fixed links: 2, modified documents: 2
Repair database complete (0 errors)

rebuild index *

Rebuilding index(es)...
Rebuilt index(es). Found 4354 link(s) in 36.727001 sec(s).

Index(es) rebuilt successfully


Wednesday, October 24, 2018

Importing and exporting dictionaries in XL-Deploy

XebiaLab XL-Deploy is a great tool, but definitely lacking important features as far as versioning and exporting/importing configuration.

If you need to programmatically generate a Dictionary (rather than using the painfully limited UI), you can take a look at this code

In my case, I create a dictionary "pippo.dict" with a couple of keys (pippo, paperino...)

then from the cli:

print mypippo



cd /home/centos/xldeploy/xl-deploy-8.2.0-server/export
cat configuration-items.xml

there are several entries <entry key="pippo">pluto</entry>

you can add/delete/edit those entries, then create a new file (with a slightly different name, 56 instead of 36):

zip configuration-items.xml

and in the CLI:


and lo and behold, the updated properties are in the dictionary!

Friday, October 19, 2018

Getting configuration information from Nexus FOR FREE

One VERY SIMPLE way to log all the Nexus 3 configuration in the nexus.log is to enable debug logging (Administration/Logging/ set the ROOT logger at DEBUG level), then navigate to the Repositories/Roles/Users administration page. You will see that precious JSON is logged in nexus.log, containing all the most minute details of the Repositories/Roles/User configuration.

Programmatically you can achieve the same with a HTTP POST to http://mynexusserver:8081/service/extdirect with this JSON request, Content-Type application/json



It would be really cool if such API was made available through SwaggerUI... Nexus 3 is very very primitive as far as API is concerned.

Internally, those actions coreui_Blobstore , coreui_User, coreui_Repository are mapped this way:

action class '' mapped to 'coreui_User'

action class '' mapped to 'coreui_Repository'

action class '' mapped to 'coreui_Blobstore'

which are in the plugin/nexus-coreui-plugin area as Groovy classes (this for Nexus 3.10... I think in Nexus 3.13 things have changed..)

Wednesday, October 17, 2018

bintray endless redirection for

The Scala folks running this repository don't seem to understand the importance of running their stuff behind a Proxy Server, so that all elements come from the same domain.... instead, they send you HTTP 302 (MOVED) and force you to hop from to and then to .... which is outrageously cumbersome if you run your Nexus repository from behind a Firewall, then you have to open individually each subdomain... otherwise you end up with the dreaded " HTTP/1.1 407 Proxy Authentication Required "

2018-10-16 16:21:19,993+0200 DEBUG [qtp72695066-17874] *UNKNOWN - > GET /scalasbt/sbt-plugin-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/jars/sbt-native-packager.jar HTTP/1.1

2018-10-16 16:21:20,102+0200 DEBUG [qtp72695066-17874] *UNKNOWN - < HTTP/1.1 302 Moved Temporarily @ 108.4 ms 2018-10-16 16:21:20,102+0200 DEBUG [qtp72695066-17874] *UNKNOWN - > GET /sbt/sbt-plugin-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/jars/sbt-native-packager.jar HTTP/1.1

2018-10-16 16:21:20,193+0200 DEBUG [qtp72695066-17874] *UNKNOWN - < HTTP/1.1 302 @ 90.77 ms 2018-10-16 16:21:20,195+0200 DEBUG [qtp72695066-17874] *UNKNOWN - > GET /3f/3f786b85a05e14c7ed5c24fbefbee19fbaa345e1db5d16fa9fa348c2a4e4789e?__gda__=exp=1539700400~hmac=9d5b250bffebb7cedf93ef28933b588c8788e9a7b20415dbe12e255435bf5ede&response-content-disposition=attachment%3Bfilename%3D%22sbt-native-packager.jar%22&response-content-type=application%2Fjava-archive&requestInfo=U2FsdGVkX1_tU3jkSNxcBb5JrmKzZS9pVZUOhb41Zj_AapUhiUGbx2fl-2B2bTDZvRaC1DmJfpw37KETEYGfMyBkdRqY-gknijMaFBx-HSJPsgC4aYd6Ejwpe2uzTSrTmhIF7HIgBbnG6hm8PxLHTvaGWPkWDnEacMK9-YMvxz8zphO4eHB46kniHIOc-vop&response-X-Checksum-Sha1=f8ab68145e3a23da45be0847f114065aa2fc0f54&response-X-Checksum-Sha2=3f786b85a05e14c7ed5c24fbefbee19fbaa345e1db5d16fa9fa348c2a4e4789e HTTP/1.1

2018-10-16 16:21:20,204+0200 DEBUG [qtp72695066-17874] *UNKNOWN - < HTTP/1.1 407 Proxy Authentication Required @ 9.761 ms

Monday, October 15, 2018

backing up the Nexus configuration

Using the built-in procedure is risky - to say the least. I was unable to make it work (the restore part, I mean).

You can do this (see ):

java -jar /opt/sonatype/nexus/lib/support/nexus-orient-console.jar

CONNECT create database plocal:/home/centos/nexus310/sonatype-work/nexus3/db/component admin admin

#to export, use this:
export database component-export

#to import, use this:
drop database
create database plocal:/home/centos/nexus310/sonatype-work/nexus3/db/component
import database component-export.json.gz

I also do this:

gunzip component-export.json.gz
python -m json.tool component-export.json > component-exportPRETTY.json

and the JSON file is quite readable, probably you can even stick it into a Git repo and relax.

just replace "component" with "config" and do all over again, to backup the configuration

From an operational point of view, Nexus 3 is simply too fragile.

Installing JIRA
Linux 64 bit

cd Downloads
sudo ./atlassian-jira-software-7.12.3-x64.bin
Unpacking JRE ...
Starting Installer ...

This will install JIRA Software 7.12.3 on your computer.
OK [o, Enter], Cancel [c]

Choose the appropriate installation or upgrade option.
Please choose one of the following:
Express Install (use default settings) [1], Custom Install (recommended for advanced users) [2, Enter], Upgrade an existing JIRA installation [3]
Details on where JIRA Software will be installed and the settings that will be used.
Installation Directory: /opt/atlassian/jira 
Home Directory: /var/atlassian/application-data/jira 
HTTP Port: 8080 
RMI Port: 8005 
Install as service: Yes 
Install [i, Enter], Exit [e]

Extracting files ...

Please wait a few moments while JIRA Software is configured.
Installation of JIRA Software 7.12.3 is complete
Start JIRA Software 7.12.3 now?
Yes [y, Enter], No [n]

Please wait a few moments while JIRA Software starts up.
Launching JIRA Software ...
Installation of JIRA Software 7.12.3 is complete
Your installation of JIRA Software 7.12.3 is now ready and can be accessed
via your browser.
JIRA Software 7.12.3 can be accessed at http://localhost:8080
Finishing installation ...


generating the evaluation license key is very simple (you should create an account with Atlassian)

the product is installed for user "jira":
sudo su - jira

logs are in /opt/atlassian/jira/logs/

To troubleshoot webhooks, you should enable DEBUG loggin as default in http://localhost:8080/secure/admin/ViewLogging.jspa
then you see the webhook body being traced in /opt/atlassian/jira/logs/catalina.out

Start and stop:
sudo /etc/init.d/jira start
sudo /etc/init.d/jira stop

Spring Boot vault

which is basically same as

More JIRA on Docker

See also

docker run -d -p 8080:8080 cptactionhank/atlassian-jira:7.7.0

I need to install netstat, but I have no root access (root pw is not given), so I do:

docker exec -ti --user root elastic_agnesi /bin/sh

and I get this strange error:

OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "chdir to cwd (\"/var/atlassian/jira\") set in config.json failed: permission denied": unknown


docker exec -ti elastic_agnesi /bin/sh
chmod 777 .
chmod 777 ..

and try again connecting as root.... I have no idea why, but this time it works....

Then as root do

apt install net-tools

Then I discover that only tcp (not tcp6) ports are available, because the image doesn't support IPv6 : "cat /proc/net/if_inet6" returns nothing.

Now I start my webhook intercepting application with IPv4

java -jar bla.jar


[centos@localhost ~]$ netstat -an | grep 8090
tcp6 0 0 :::8090 :::* LISTEN


[centos@localhost ~]$ netstat -an | grep 8090
tcp 0 0* LISTEN

but still curl -X POST http://localhost:8090/greeting is not working... I am giving up and will install JIRA directly on host....

Sunday, October 14, 2018

Material UI and Spring Boot

download latest NPM here (10.12.0-CURRENT)

npx create-react-app react-material-ui
cd react-material-ui/
npm install @material-ui/core
npm install contentful

One can use rthis sample

Wednesday, October 10, 2018

Nexus Groovy scripting

Huge issue in Nexus is that you can't export/import your Users/Groups/Privileges and Repository configuration. All you can do is to take a "backup", which ends of in a folder as a completely unreadable/unversionable format.

So I was looking for

when you run a Groovy script in Nexus, you have available a predefined variable "repository", which is of type

This in turn contains a reference to a blobStoreManager and to a repositoryManager , plus a series of convenience methods to create commonly used repository formats (you are not expected to create anything fancy, most properties are assigned by default) and groups.

Key element is a object, again very disappointing since the configuration is represented by a "attribute" map (String, Map(String, Object)) which is really a stupid idea, too generic interface.

RepositoryManager has a Iterable<Repository> browse(); which returns a collection of

Sample script:


repository.repositoryManager.browse().each { Repository repo ->"Repository: $repo")"Repository Configuration: $repo.configuration")

this dumps in nexus.log the following content:

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=proxy, format=nuget, name=''}
Repository Configuration: Configuration{repositoryName='', recipeName='nuget-proxy', attributes={proxy={strictContentTypeValidation=true, contentMaxAge=1440, remoteUrl=, metadataMaxAge=1440}, negativeCache={}, storage={blobStoreName=default}, nugetProxy={}, httpclient={connection={blocked=false, autoBlock=true}}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=hosted, format=maven2, name='maven-releases'}
Repository Configuration: Configuration{repositoryName='maven-releases', recipeName='maven2-hosted', attributes={maven={versionPolicy=RELEASE, layoutPolicy=STRICT}, storage={writePolicy=ALLOW_ONCE, strictContentTypeValidation=false, blobStoreName=default}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=hosted, format=maven2, name='maven-snapshots'}
Repository Configuration: Configuration{repositoryName='maven-snapshots', recipeName='maven2-hosted', attributes={maven={versionPolicy=SNAPSHOT, layoutPolicy=STRICT}, storage={writePolicy=ALLOW, strictContentTypeValidation=false, blobStoreName=default}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=proxy, format=maven2, name='maven-central'}
Repository Configuration: Configuration{repositoryName='maven-central', recipeName='maven2-proxy', attributes={proxy={contentMaxAge=-1, remoteUrl=, metadataMaxAge=1440}, negativeCache={timeToLive=1440, enabled=true}, storage={strictContentTypeValidation=false, blobStoreName=default}, maven-indexer={}, httpclient={connection={blocked=false, autoBlock=true}}, maven={versionPolicy=RELEASE, layoutPolicy=PERMISSIVE}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=group, format=nuget, name='nuget-group'}
Repository Configuration: Configuration{repositoryName='nuget-group', recipeName='nuget-group', attributes={storage={blobStoreName=default}, nugetProxy={}, httpclient={}, group={memberNames=[nuget-hosted,]}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=hosted, format=nuget, name='nuget-hosted'}
Repository Configuration: Configuration{repositoryName='nuget-hosted', recipeName='nuget-hosted', attributes={storage={writePolicy=ALLOW, blobStoreName=default}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=group, format=maven2, name='maven-public'}
Repository Configuration: Configuration{repositoryName='maven-public', recipeName='maven2-group', attributes={maven={versionPolicy=MIXED}, group={memberNames=[maven-releases, maven-snapshots, maven-central]}, storage={blobStoreName=default}}}

which is pretty good result, at least you can capture in one go all the configuration of all your repositories.

This task will delete all your repos:


repository.repositoryManager.browse().each { Repository repo ->"DELETE Repository: $repo")

All the predefined variables are

core which is a

repository which is a

blobStore which is a
createFileBlobStore(final String name, final String path) blobStoreManager 

security which is a
User addUser(final String id, final String firstName, final String lastName, final String email, final boolean active,
final String password, final List roleIds)
Role addRole(final String id, final String name, final String description, final List privileges,
final List roles)
User setUserRoles(final String userId, final List roleIds)

If you do security.getSecuritySystem() you get an instance of this:

Good is that if you clone the github repo nexus-book-examples you can directly open the APIs in file:///home/centos/gitclones/nexus-book-examples/scripting/apidocs/index.html

List all users with their roles

import groovy.json.JsonOutput
users = security.getSecuritySystem().listUsers()
userjson = JsonOutput.toJson(users)"USERS $userjson")

or also


users = security.getSecuritySystem().searchUsers(new UserSearchCriteria())"users=" + users)

Add users and roles:

privileges = [

security.addRole("deployer", "deployer", "deployment on all repositories", privileges, [])

security.addUser(userName, firstName, lastName, email, true, password, ["deployer"])

creating blobstores:

def list = ["dockerGroup", "mynpm", "pippo", "ivy", "dockerhosted", "dockerProxy", "jcenter", "pythonProxy"]
for (item in list) {"creating blobstore " + item)
    blobStore.createFileBlobStore(item, item)

creating hosted repositories


repository.createDockerHosted(name = 'pippo', httpPort = 8123, httpsPort = null, blobStoreName = 'docker', strictContentTypeValidation=true, v1Enabled=true, writePolicy = WritePolicy.ALLOW, forceBasicAuth=false)

repository.createMavenHosted(name = 'ivyhosted', blobStoreName = 'ivy', strictContentTypeValidation = true, versionPolicy = VersionPolicy.RELEASE, writePolicy= WritePolicy.ALLOW_ONCE, layoutPolicy=LayoutPolicy.PERMISSIVE )

You cannot delete anonymous, the only way is to update it:


// the following 6 lines are not required
anonymous = security.getSecuritySystem().getUser("anonymous", "default")"Anonymous before=" + anonymous)
Set allRoles = security.getSecuritySystem().listRoles();"allRoles=" + allRoles)
advRole = allRoles.find{it.roleId=='ADVRole'}"advRole=" + advRole)

// these 2 lines below do the job
advRoleIdentifier = new RoleIdentifier('default', 'ADVRole');
security.getSecuritySystem().setUsersRoles("anonymous", "default", [advRoleIdentifier].toSet())

Script to create/update a role (without affecting existing users using that role, if existing)

import static

privileges = [

createOrUpdateRole("pippo", privileges, [])
createOrUpdateUser("pippouser", [ "pippo", "nx-admin" ])

def createOrUpdateRole(rolename, privileges, roles) {"calling createOrUpdateRole with parameters rolename=" + rolename + " privileges=" + privileges + " roles=" + roles)
 Set allRoles = security.getSecuritySystem().listRoles()
 Role role = allRoles.find{it.roleId==rolename}
 if (role != null) {"existing role=" + role)
  role.setRoles(roles.toSet())"updating role=" + role)
  // security.securitySystem.getAuthorizationManager(DEFAULT_SOURCE).deleteRole(role.roleId)
  security.securitySystem.getAuthorizationManager(DEFAULT_SOURCE).updateRole(role)"role updated=" + role)
 else {"adding role " + rolename)
  security.addRole(rolename, rolename, rolename, privileges, roles)"role " + rolename + " successfully added")

def createOrUpdateUser(username, roles) {"calling createOrUpdateUser with parameters username=" + username + " roles=" + roles)
 Set allUsers = security.getSecuritySystem().listUsers()
 User user = allUsers.find{it.userId == username}
 if (user != null) {"updating existing user=" + user)
  Set roleIdentifiers = new HashSet()
  roles.each{ role -> roleIdentifiers.add(new RoleIdentifier("default", role))}
  security.getSecuritySystem().setUsersRoles(username, "default", roleIdentifiers)
 else {
  security.addUser(username, username, username, username + "", true, username, roles)

Eclipse jee-2018-09 hangs upon restarting

Eclipse jee-2018-09 hangs upon restarting

I do a "ps -ef | grep -i eclipse" then a jstack on the process, to find out that:

ModalContext" #136 prio=6 os_prio=0 tid=0x00007fbe7885f000 nid=0x2744 waiting for monitor entry [0x00007fbdc980f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
 at org.eclipse.swt.widgets.Display.asyncExec(
 - waiting to lock <0x00000000c030b110> (a java.lang.Class for
 at org.eclipse.jface.operation.AccumulatingProgressMonitor.beginTask(
 at org.eclipse.core.runtime.ProgressMonitorWrapper.beginTask(
 at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$CancelableProgressMonitorWrapper.beginTask(
 at org.eclipse.core.runtime.ProgressMonitorWrapper.beginTask(
 at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$
 at org.eclipse.jface.operation.ModalContext$

"Worker-33: Building workspace" #133 prio=5 os_prio=0 tid=0x00007fbe54f7b800 nid=0x2731 waiting for monitor entry [0x00007fbdf8133000]
   java.lang.Thread.State: BLOCKED (on object monitor)
 - waiting to lock <0x00000000c030b110> (a java.lang.Class for
 at org.eclipse.ui.internal.UILockListener.isUI(
 at org.eclipse.ui.internal.UILockListener.aboutToRelease(
 - locked <0x00000000c648be58> (a
 at org.eclipse.core.internal.resources.WorkManager.beginUnprotected(
 at org.eclipse.wst.jsdt.internal.core.JavaModelManager.initializeAllContainers(
 at org.eclipse.wst.jsdt.internal.core.JavaModelManager.getJsGlobalScopeContainer(
 at org.eclipse.wst.jsdt.core.JavaScriptCore.getJsGlobalScopeContainer(
 at org.eclipse.wst.jsdt.internal.core.JavaProject.resolveClasspath(
 at org.eclipse.wst.jsdt.internal.core.JavaProject.getResolvedClasspath(
 at org.eclipse.wst.jsdt.internal.core.DeltaProcessor.validateClasspaths(
 at org.eclipse.wst.jsdt.internal.core.DeltaProcessor.resourceChanged(
 at org.eclipse.wst.jsdt.internal.core.DeltaProcessingState.resourceChanged(
 at org.eclipse.core.internal.resources.Workspace.broadcastBuildEvent(

it seems related to this bug

Just kill the bastard and move on.

Eclipse is a total piece of shit - they should simply rewrite it from scratch using a better design. Time invested in maintaining this old elephant is totally wasted.

Nexus programmatically create Repositories

Nexus API sucks - big time.

This is a desperate attempt to automate stuff.

git clone
cd ./nexus-book-examples/scripting/complex-script

docker run -d -p 8081:8081 --name nexus sonatype/nexus3:3.10.0

check the logs by
docker exec -ti nexus /bin/bash
more /opt/sonatype/sonatype-work/nexus3/log/nexus.log

rm -rf /home/centos/.groovy/grapes/
rm -rf /home/centos/.m2/repository/

You can easily test your scripts from the Nexus UI (create execute script UI) , and also debut them remotely from Intellij :

Try running this script:


it can't be easier!

The RepositoryAPI is available here

Repository createMavenHosted(final String name,
final String blobStoreName,
final boolean strictContentTypeValidation,
final VersionPolicy versionPolicy,
final WritePolicy writePolicy,
final LayoutPolicy layoutPolicy);


repository.createMavenHosted('private-again', 'default', true,,,

To list repositories (unfortunately it returns only partial information about the Repository):

curl -X GET --header 'Accept: application/json' 'http://localhost:8081/service/rest/beta/repositories'

[ {
  "name" : "",
  "format" : "nuget",
  "type" : "proxy",
  "url" : "http://localhost:8081/repository/"
}, {
  "name" : "maven-releases",
  "format" : "maven2",
  "type" : "hosted",
  "url" : "http://localhost:8081/repository/maven-releases"
}, {
  "name" : "maven-snapshots",
  "format" : "maven2",
  "type" : "hosted",
  "url" : "http://localhost:8081/repository/maven-snapshots"
}, {
  "name" : "maven-central",
  "format" : "maven2",
  "type" : "proxy",
  "url" : "http://localhost:8081/repository/maven-central"
}, {
  "name" : "nuget-group",
  "format" : "nuget",
  "type" : "group",
  "url" : "http://localhost:8081/repository/nuget-group"
}, {
  "name" : "nuget-hosted",
  "format" : "nuget",
  "type" : "hosted",
  "url" : "http://localhost:8081/repository/nuget-hosted"
}, {
  "name" : "maven-public",
  "format" : "maven2",
  "type" : "group",
  "url" : "http://localhost:8081/repository/maven-public"
} ]

Ref: about Groovy Scripting in Nexus

Tuesday, October 9, 2018

centos filesystem ntfs not configured in kernel

trying to install an external HD (Windows formatted) on a Centos box...

centos@localhost ~]$ sudo fdisk -l /dev/sdc2

Disk /dev/sdc2: 4000.7 GB, 4000650887168 bytes, 7813771264 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 33553920 bytes
Disk label type: dos
Disk identifier: 0x6e697373

This doesn't look like a partition table
Probably you selected the wrong device.

     Device Boot      Start         End      Blocks   Id  System
/dev/sdc2p1   ?  1936269394  3772285809   918008208   4f  QNX4.x 3rd part
Partition 1 does not start on physical sector boundary.
/dev/sdc2p2   ?  1917848077  2462285169   272218546+  73  Unknown
Partition 2 does not start on physical sector boundary.
/dev/sdc2p3   ?  1818575915  2362751050   272087568   2b  Unknown
Partition 3 does not start on physical sector boundary.
/dev/sdc2p4   ?  2844524554  2844579527       27487   61  SpeedStor
Partition 4 does not start on physical sector boundary.

Partition table entries are not in disk order
[centos@localhost ~]$ 

sudo yum install epel-release

Package epel-release-7-11.noarch already installed and latest version
Nothing to do

find /lib/modules/ | grep ntfs

nothing is found!

sudo yum install ntfs-3g -y

and now it works! Great! New mountpoint is /run/media/centos/Seagate\ Expansion\ Drive/


Sunday, September 30, 2018

Nexus and Groovy for Setup Automation

Amazingly few people automate their Nexus administration. I guess the fault lies mostly in the company behind Nexus, who does very little to make their API usable and well documented.

This post made me discover this API:

Very good reading also here about using the Nexus book examples to automate the execution of these Groovy/Java scripts.

References on same topic of Automation (via REST api)

Wednesday, September 26, 2018

git delete all tags matching a regex

this will delete all remote tags containig the "iap-copy" string (more complex cases can be achieved with egrep)

git clone myrepourl
cd myproject
git tag --list | grep iap-copy | sort > allnaughtytags.txt
for mytag in `cat allnaughtytags.txt`; do git push --delete origin $mytag ; done 

The method is very slow.... there are much faster ways, but this is very simple and reliable

tested with git 1.9.4

Friday, September 21, 2018

Parsing command line arguments in Spring etc

lots of frameworks are reported here:

but eventually I just want to do it using Spring classes

The advantage in Spring is that you can directly bind the command line arguments to attributes, there is an example here

A very simple example:

package org.pierre.clidemo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.boot.CommandLineRunner;

public class DemoApplication implements CommandLineRunner {

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

 public void run(String... args) throws Exception {
  PropertySource ps = new SimpleCommandLinePropertySource(args);
  // --file=pippo.txt --language=EN_TO_DE --firstOriginal=true
  System.out.println("file=" + ps.getProperty("file"));
  System.out.println("language=" + ps.getProperty("language"));
  System.out.println("firstOriginal=" + ps.getProperty("firstOriginal"));

and of course the JOptCommandLinePropertySource version is more robust...

Interesting also the project, but only to write CLI applications

Wednesday, September 19, 2018

Eclipse Linux Tools (Docker Plugin) source code

git clone git://

jars are installed NOT under the Eclipse installation folder, BUT here


Here they explain how to submit a bug

Unfortunately there is a bug in org.eclipse.linuxtools.internal.docker.ui.wizards.ContainerCopyTo

    public boolean performFinish() {
        boolean finished = mainPage.finish();
        if (finished) {
            target = mainPage.getDestination().toOSString();
            sources = mainPage.getFilesToCopy();
        return finished;

If you run Eclipse on Windows, and the docker daemon runs on Linux, the toOSString() formats any path into the Windows format, which is not recognized by Linux. So you can't specify "/var" because it will be turned into "\\var" which obviously fails on Linux. bug submitted

Monday, September 17, 2018

Nexus Maven repository migration

I need to migrate a Nexus 2.14 Maven repository to Nexus 3.10.

Unfortunately the Nexus product doesn't care much about migrations... probably they believe that, once installed, their product is immovable, like a sick elephant.

With a Nexus 2.14 to Nexus 2.14 migration, the repository structure is so simple that you can do it with a rsync.
But Nexus 3.10 is a totally different beast.

Luckily there are people who wrote tools:

I have to migrate from http://localhost:8081/nexus/content/repositories/releases/ (Nexus 2.14) to http://localhost:8181/repository/releases/ (Nexus 3.10)

git clone
cd maven-repository-tools
mvn package
java -jar maven-repository-provisioner/target/maven-repository-provisioner-1.3.2-SNAPSHOT-jar-with-dependencies.jar

java -jar maven-repository-provisioner/target/maven-repository-provisioner-1.3.2-SNAPSHOT-jar-with-dependencies.jar -s http://localhost:8081/nexus/content/repositories/releases/ -t http://localhost:8181/repository/releases/ -u admin -p admin123 -a org.pierre:pvjoinfacestest:war:1.0

tragically, the tool doesn't allow wildcards.... so you must know in advance the gav of ALL the artifacts you have to migrate.... my impression is also that the .war is not really uploaded!

I am trying this one

copy to my /home/centos/nexus214/sonatype-work/nexus/storage/releases folder, then run

./ -r http://localhost:8181/repository/releases/ -u admin -p admin123

and it works!

Friday, September 14, 2018

NordVPN programmatic API

'address': '/user/address',
'config': '/files/zipv2',
'nameserver': '/dns/smart',
'server': '/server',
'stats': '/server/stats',
'user': '/user/databytoken'

list of all NordVPN servers:

id 98288
ip_address ""
search_keywords []
categories […]
name "Indonesia #2"
domain ""
price 0
flag "ID"
country "Indonesia"
lat -6.174444
long 106.829444
load 55
ikev2 true
openvpn_udp true
openvpn_tcp true
socks true
proxy true
pptp false
l2tp false
openvpn_xor_udp false
openvpn_xor_tcp false
proxy_cybersec true
proxy_ssl true
proxy_ssl_cybersec true

return my current IP downloads a file (some 20 MB) full of .ovpn files, for each server, with PKI key to connect to the server returns a list of IPs, probably of the NordVPN dns server here you find how to login into API :

Monday, September 3, 2018

Nexus HTTP/1.1 407 Proxy Authentication Required

While trying to connect to and over a corporate proxy with these 2 sites whitelisted, we keep getting: - Exception HTTP/1.1 407 Proxy Authentication Required checking remote for update, proxy repo ivyreleases_proxy failed to fetch com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml with status line HTTP/1.1 407 Proxy Authentication Required, content not in cache.

If you enable ROOT logging at DEBUG (menu Support/Logging in Nexus console) you will see that a redirect is taking place, but the LAZY Nexus developer only logs the message and not the additional ESSENTIAL parameters to understand what is going on, that is a redirection to

2018-09-03 13:11:48,044+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - Fetching: GET HTTP/1.1
2018-09-03 13:11:48,046+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - > GET /typesafe/ivy-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml HTTP/1.1
2018-09-03 13:11:48,046+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - Connection request: [route: {tls}->http://ourproxyserver:8080->][total kept alive: 0; route allocated: 0 of 20; total allocated: 0 of 200]
2018-09-03 13:11:48,046+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - Connection leased: [id: 478][route: {tls}->http://ourproxyserver:8080->][total kept alive: 0; route allocated: 1 of 20; total allocated: 1 of 200]
2018-09-03 13:11:48,448+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - < HTTP/1.1 302 Moved Temporarily @ 402.5 ms
2018-09-03 13:11:48,448+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - Connection [id: 478][route: {tls}->http://ourproxyserver:8080->] can be kept alive for 30.0 seconds
2018-09-03 13:11:48,449+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - Connection released: [id: 478][route: {tls}->http://ourproxyserver:8080->][total kept alive: 1; route allocated: 1 of 20; total allocated: 1 of 200]
2018-09-03 13:11:48,449+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - > GET /typesafe/ivy-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml HTTP/1.1
2018-09-03 13:11:48,449+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - Connection request: [route: {tls}->http://ourproxyserver:8080->][total kept alive: 1; route allocated: 0 of 20; total allocated: 1 of 200]
2018-09-03 13:11:48,449+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - Connection leased: [id: 479][route: {tls}->http://ourproxyserver:8080->][total kept alive: 1; route allocated: 1 of 20; total allocated: 2 of 200]
2018-09-03 13:11:48,466+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - Connection released: [id: 479][route: {tls}->http://ourproxyserver:8080->][total kept alive: 1; route allocated: 0 of 20; total allocated: 1 of 200]
2018-09-03 13:11:48,466+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - < HTTP/1.1 407 Proxy Authentication Required @ 17.12 ms
2018-09-03 13:11:48,466+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - Response: HttpResponseProxy{HTTP/1.1 407 Proxy Authentication Required [Proxy-Authenticate: NTLM, Cache-Control: no-cache, Pragma: no-cache, Content-Type: text/html; charset=utf-8, Proxy-Connection: close, Connection: close, Content-Length: 850] org.apache.http.entity.BufferedHttpEntity@3326370a}
2018-09-03 13:11:48,466+0200 DEBUG [qtp46263989-6144]  *UNKNOWN - Status: HTTP/1.1 407 Proxy Authentication Required
2018-09-03 13:11:48,467+0200 WARN  [qtp46263989-6144]  *UNKNOWN - Exception HTTP/1.1 407 Proxy Authentication Required checking remote for update, proxy repo ivyreleases_proxy failed to fetch com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml with status line HTTP/1.1 407 Proxy Authentication Required, content not in cache. HTTP/1.1 407 Proxy Authentication Required
 at$$Lambda$269/ Source)
 at javax.servlet.http.HttpServlet.service(
 at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(
 at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(
 at org.apache.shiro.web.servlet.AdviceFilter.executeChain(
 at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(
 at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(
 at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(
 at org.apache.shiro.web.servlet.AdviceFilter.executeChain(
 at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(
 at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(
 at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(
 at org.apache.shiro.web.servlet.AdviceFilter.executeChain(
 at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(
 at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(
 at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(
 at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(
 at org.apache.shiro.web.servlet.AbstractShiroFilter$
 at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(
 at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(
 at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(
 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(
 at org.eclipse.jetty.servlet.ServletHandler.doHandle(
 at org.eclipse.jetty.server.handler.ScopedHandler.handle(
 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(
 at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(
 at org.eclipse.jetty.server.session.SessionHandler.doHandle(
 at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(
 at org.eclipse.jetty.server.handler.ContextHandler.doHandle(
 at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(
 at org.eclipse.jetty.servlet.ServletHandler.doScope(
 at org.eclipse.jetty.server.session.SessionHandler.doScope(
 at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(
 at org.eclipse.jetty.server.handler.ContextHandler.doScope(
 at org.eclipse.jetty.server.handler.ScopedHandler.handle(
 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(
 at com.codahale.metrics.jetty9.InstrumentedHandler.handle(
 at org.eclipse.jetty.server.handler.HandlerCollection.handle(
 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(
 at org.eclipse.jetty.server.Server.handle(
 at org.eclipse.jetty.server.HttpChannel.handle(
 at org.eclipse.jetty.server.HttpConnection.onFillable(
 at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(
 at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(
 at org.eclipse.jetty.util.thread.ReservedThreadExecutor$
 at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(
 at org.eclipse.jetty.util.thread.QueuedThreadPool$

For , you might need to whitelist also