Surfing through logs with less

shift g: goes to end.
shift f: tails the file.

  – ctrl+c: switch to normal mode (no tails)

?: search upwards
/: search downward
 – n: search next match in current direction
 – shift n: search next match in counter direction
Also useful to find 2 or more words in one line is the regex:
Word1.+Word2 finds both words in the same line
As an extra to review logs, it is also useful the command grep with options after and before:
grep -A: lines after match
grep -B: lines before match

Pass parameters to java main method using graddle

To pass for example a param “-a” with value “” to the static void main method that tha graddle task will run,  you will need to :

  • add following entry to file, or assert that it is already there:
    run {
        if (project.hasProperty("appArgs")) {
            args =
  • run graddle on the following form:
    gradle  run  -PappArgs="['-a',  '']"

Create own collectors

Sometimes it is useful to be able perform several actions extracting several actions with a stream pass. It can be achieved building our own collector. For example, suppose we need to get the maximal and minimal values of a series. So can we achieve it using collectors.

public class MaxMinCollector2 implements Collector<Integer, MaxMinContainer, MaxMinContainer>{

    public void accumulate(MaxMinContainer container, Integer val){

        if(container.max == null){
            container.max = val;
        }else if(container.max < val){
            container.max = val;

        if(container.min == null){
            container.min = val;
        }else if(container.min > val){
            container.min = val;


    public MaxMinContainer combine(MaxMinContainer a, MaxMinContainer b){
        if(a.max == null){
            b.getMax().ifPresent(v -> a.max = v);
        }else {
            b.getMax().ifPresent(v -> a.max = a.max < v ? v : a.max);

        if(a.min == null){
            b.getMin().ifPresent(v -> a.min = v);
        }else {
            b.getMax().ifPresent(v -> a.min = a.min > v ? v : a.min);

        return a;

    public Supplier<MaxMinContainer> supplier() {
        return MaxMinContainer::new;

    public BiConsumer<MaxMinContainer, Integer> accumulator() {
        return this::accumulate;

    public BinaryOperator<MaxMinContainer> combiner() {
        return this::combine;

    public Function<MaxMinContainer, MaxMinContainer> finisher() {
        return (a) -> a;

    public Set<Characteristics> characteristics() {
        return new HashSet<>(Arrays.asList(Characteristics.IDENTITY_FINISH, Characteristics.UNORDERED));

and its corresponding test:

package de.lacambra.utils.collectors;

import org.junit.Before;
import org.junit.Test;


import static;
import static org.junit.Assert.assertThat;

public class MaxMinCollectorTest {

    MaxMinCollector cut;

    public void setUp() throws Exception {
        cut = new MaxMinCollector();

    public void testMaxMinSerie() {

        MaxMinCollector result = IntStream.of(1, 2, 3, 4, 5, 6)
                .collect(MaxMinCollector::new, MaxMinCollector::accumulate, MaxMinCollector::combine);

        assertThat(result.getMax().get(), is(6));
        assertThat(result.getMin().get(), is(1));

        result = IntStream.of(1000, 2, 3342, 421, 523, 6)
                .collect(MaxMinCollector::new, MaxMinCollector::accumulate, MaxMinCollector::combine);

        assertThat(result.getMax().get(), is(3342));
        assertThat(result.getMin().get(), is(2));

    public void emptySerie(){
        MaxMinCollector result = IntStream.of()
                .collect(MaxMinCollector::new, MaxMinCollector::accumulate, MaxMinCollector::combine);

        assertThat(result.getMax().isPresent(), is(false));
        assertThat(result.getMin().isPresent(), is(false));

    public void oneValueSerie(){
        MaxMinCollector result = IntStream.of(34)
                .collect(MaxMinCollector::new, MaxMinCollector::accumulate, MaxMinCollector::combine);

        assertThat(result.getMax().get(), is(34));
        assertThat(result.getMin().get(), is(34));

Create a correct 201 Created response with JAX-RS

public Response createProject(@Context UriInfo uriInfo, JsonObject json) {
        Project project = projectConverter.fromJson(json);
        project = em.merge(project);

        URI uri = uriInfo.getBaseUriBuilder()
                .resolveTemplate(PathExpressions.workspaceId, getCurrentWorkspace().getId())
                .resolveTemplate(PathExpressions.projectId, project.getId())

        return Response.created(uri).build();
The @Context UriInfo uriInfo provides information about the current URI. 
The .path(ProjectResource.class)  call will return the path used for the ProjectResource.class. 
The .resolveTemplate("{workspaceId:\\d+}", getCurrentWorkspace().getId())  will replace the workspaceId template variable for the actual wokspace id.

Once the whole path has been created, it is only needed to put it into a created response.

Collect into Jsonp JsonArray using without using foreach

Each collector has three parts:

  • A supplier: provides with instances of the accumulator.
  • An accumulator: accumulates the objects being collected. Several instances of accumulator can be used.
  • A combiner: combines all the accumulator putting all collected objects together.

For the JsonArray the combiner, accumulator  and combiener are respectively:

JsonArrayBuilder createArrayBuilder()
JsonArrayBuilder add(JsonValue value)
JsonArrayBuilder add(JsonArrayBuilder builder)

    public JsonArray getArray(Jsonable[] objects) {
        return Stream.of(objects).map(Jsonable::toJson)


    public static class Jsonable {

        public JsonObject toJson() {
            return Json.createObjectBuilder().add("someId",;