Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Sunday, 3 December 2017

This week 14/2017 - Jollyday

Jollyday is a small library to get dates of holidays. 
When you open project documentation page, you can think that this project is dead. The sourceforge page wasn't updated for last 2 years. However when you check GitHub repository, it is still developed since 2010. When I write this blog the most fresh version for JDK8 is 0.5.2.

Jollyday handles fixed, related to day of month and religious holidays. To be more advanced, it handles additional rules to define moving free days related to holidays, ex when holiday is on Saturday, next Monday will be holiday as well.

Below there is piece US configuration file. The Jollyday jar file includes default configuration for 64 countries. Some of them include holidays changes in time in the past. Polish configuration doesn't.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
..
14
15
16
17
18
19
20
<tns:Configuration hierarchy="us" description="United States"
                   xmlns:tns="http://www.example.org/Holiday" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.example.org/Holiday/Holiday.xsd">
    <tns:Holidays>
        <tns:Fixed month="JANUARY" day="1" descriptionPropertiesKey="NEW_YEAR"/>
        <tns:Fixed month="JULY" day="4" validFrom="1776" descriptionPropertiesKey="INDEPENDENCE"/>
        <tns:Fixed month="NOVEMBER" day="11" validFrom="1938" descriptionPropertiesKey="VETERANS"/>
        <tns:Fixed month="DECEMBER" day="25" descriptionPropertiesKey="CHRISTMAS"/>
        <tns:Fixed month="MAY" day="30" validFrom="1869" validTo="1967" descriptionPropertiesKey="MEMORIAL"/>
        <tns:FixedWeekday which="LAST" weekday="MONDAY" month="MAY" validFrom="1968" descriptionPropertiesKey="MEMORIAL"/>
        <tns:FixedWeekday which="FIRST" weekday="MONDAY" month="SEPTEMBER" validFrom="1895" descriptionPropertiesKey="LABOUR_DAY"/>
        <tns:FixedWeekday which="FOURTH" weekday="THURSDAY" month="NOVEMBER" validFrom="1863" descriptionPropertiesKey="THANKSGIVING"/>
    </tns:Holidays>
....
    <tns:SubConfigurations hierarchy="la" description="Louisiana">
        <tns:Holidays>
            <tns:FixedWeekday which="THIRD" weekday="MONDAY" month="JANUARY" validFrom="1986" descriptionPropertiesKey="MARTIN_LUTHER_KING"/>
            <tns:ChristianHoliday type="GOOD_FRIDAY"/>
            <tns:ChristianHoliday type="MARDI_GRAS"/>
        </tns:Holidays>
    </tns:SubConfigurations>

The HolidayManager is main interface of Jollyday library. Below there is a piece of code which create HolidayManager instance for US using default configuration.

1
2
ManagerParameter params = ManagerParameters.create(Locale.US));
HolidayManager holidayManager = HolidayManager.getInstance(params);

If we'd like to get holidays for US we need to execute code as below.

1
holidayManager.getHolidays(2017)


If we'd like to get holidays for Louisiana in US we need to call code as below


1
holidayManager.getHolidays(2017, "la")

It is possible to create deeper hierarchy of calendar. You must only create sub-configuration for this node and call get Holidays with additional code - code of sub-configuration.

To use custom configuration, you need create ManagerParameters from URL where is configuration file available, ex


1
2
3
URL url = ClassLoader.getSystemResource("Holidays_pl.xml");
ManagerParameter params = ManagerParameters.create(url);
HolidayManager m = HolidayManager.getInstance(params);

Below I added a few example of most common usage of HolidayManager.

1
2
3
4
5
m.getHolidays(2017)
m.getHolidays(LocalDate.now(), LocalDate.now().plusYears(5))
m.isHoliday(LocalDate.now())
m.isHoliday(LocalDate.now(), "an")
m.isHoliday(LocalDate.now(), HolidayType.UNOFFICIAL_HOLIDAY)

For more demanding, it is possible to implement:
  • country specific HolidayManager
  • configuration data source
  • change implementation of parsers
Then you need create your own properties as below (default properties file)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
manager.impl=de.jollyday.impl.DefaultHolidayManager
# Holiday manager for Japan implements some specific Japanese holiday rule.
manager.impl.jp=de.jollyday.impl.JapaneseHolidayManager
# Implementation class for holiday configurations
configuration.datasource.impl=de.jollyday.datasource.impl.XmlFileDataSource

# Configure the parsers to be used for each individual configuration type
parser.impl.de.jollyday.config.Fixed=de.jollyday.parser.impl.FixedParser
parser.impl.de.jollyday.config.FixedWeekdayInMonth=de.jollyday.parser.impl.FixedWeekdayInMonthParser
parser.impl.de.jollyday.config.IslamicHoliday=de.jollyday.parser.impl.IslamicHolidayParser
parser.impl.de.jollyday.config.ChristianHoliday=de.jollyday.parser.impl.ChristianHolidayParser
parser.impl.de.jollyday.config.RelativeToFixed=de.jollyday.parser.impl.RelativeToFixedParser
parser.impl.de.jollyday.config.RelativeToWeekdayInMonth=de.jollyday.parser.impl.RelativeToWeekdayInMonthParser
parser.impl.de.jollyday.config.FixedWeekdayBetweenFixed=de.jollyday.parser.impl.FixedWeekdayBetweenFixedParser
parser.impl.de.jollyday.config.FixedWeekdayRelativeToFixed=de.jollyday.parser.impl.FixedWeekdayRelativeToFixedParser
parser.impl.de.jollyday.config.EthiopianOrthodoxHoliday=de.jollyday.parser.impl.EthiopianOrthodoxHolidayParser
parser.impl.de.jollyday.config.RelativeToEasterSunday=de.jollyday.parser.impl.RelativeToEasterSundayParser

and setting VM options:

1
-Dde.jollyday.config.urls=file:/some/path/new.properties,http://myserver/some/path/further.properties,jar:file:myLibrary.jar!/my.properties  

I didn't find out if data source or parsers can be country specific and how to create your own parser.

Resources:
  1. jollyday.sourceforge.net
  2. github repository


Wednesday, 3 May 2017

This week 9/2017 - The REST client API

There are a few implementation of REST client for Java. I will compare 3, I think, most popular implementations.
  1. Jersey (v. 2.25.x)
  2. Spring Web (v. 3.2.x)
  3. Apache CXF (v. 3.0.x)
My goal is to create component which can:
  1. Connect by secure channel - SSL
  2. Authentication bu Basic authorization mechanism.
  3. Send custom message.
  4. Read response and deserialize it into object.
So most common use of client. I was pointing to: flexible interface, clean code - nothing special. So I created following Java code


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import java.util.Arrays;
import java.util.Base64;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import org.apache.cxf.jaxrs.client.WebClient;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

public class App {

 // Apache CXF
 private static WebClient createWebClient() {
  return WebClient.create(getUrl(), "aa", "bbc", null);
 }
 private void testWebClient(){
  System.out.println("\n\ntestWebClient:");
//  System.out.println(createWebClient().path("todo22").accept(MediaType.TEXT_XML).get(Todo2.class));
  System.out.println(createWebClient().path("todo22").get(Todo2.class));
  System.out.println(createWebClient().path("todo22").get(String.class));
 }

 // Jersey
 private static Client createWebTarget() {
  HttpAuthenticationFeature authenticationFeature = HttpAuthenticationFeature.basic("aa", "bbc");
  return ClientBuilder.newBuilder().newClient().register(authenticationFeature);
 }

 private void testWebTarget(){
  WebTarget service = createWebTarget().target(getUrl());
  System.out.println("\n\ntestWebTarget :");
//  System.out.println(service.path("todo22").request(MediaType.TEXT_XML).get(Todo2.class));
  System.out.println(service.path("todo22").request().get(Todo2.class));
  System.out.println(service.path("todo22").request().get(String.class));
 }

 // Spring Web Rest
 private static HttpHeaders getHeaders(){
  String plainCredentials="aa:bbc";
  String base64Credentials = new String(Base64.getEncoder().encode(plainCredentials.getBytes()));

  HttpHeaders headers = new HttpHeaders();
  headers.add("Authorization", "Basic " + base64Credentials);
  headers.setAccept(Arrays.asList(org.springframework.http.MediaType.TEXT_XML));
  return headers;
 }

 private void testRestTemplate(){
  System.out.println("\n\ntestRestTemplate :");
  RestTemplate restTemplate = new RestTemplate();

  // restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
  restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
  HttpEntity<String> request = new HttpEntity<String>(getHeaders());
  System.out.println(restTemplate.exchange(getUrl() + "todo22", HttpMethod.GET, request, Todo2.class).getBody());
  System.out.println(restTemplate.exchange(getUrl() + "todo22", HttpMethod.GET, request, String.class).getBody());
 }

In my opinion the simplest interface has Apache CXF but you need to remember to create new instance for multiple services.
Jersey interface looks to be it most powerful. At the beginning there is created some service client template - core of client. Then every time when path method is executed there is created new instance of client with resource name.
Jersey support all kind of authentication methods providing tool. It is opposite to Spring Web RestTemplate where I had to prepare manually authorization header. Spring Web REST required much more code then two other solutions.

Resources:

This week 8/2017

In this post I will write two small tips.

Slf4J - has one handy feature. One interface solves two problems:
1) firstly it check if message will be used, then transform parameters to String type and build all message,
2) helps to have clean code without concatenation of parameters

LOGGER.debug("Test message {} {} {}{}{}{}{}{}{}", 3, "+", 3, =, null, " 6");

Earlier I use to check logging level manually and use to format messages by String::printf


Lombok - builder pattern is great pattern to create immutable value object with many attributes. Lombok does it for you, you have only to add @Builder annotation. Unfortunately it has other standard of calling setter method (there is no set prefix) and it is useless to create builder for inheritance’s class.

Bellow I compare simple class with lombok annotations and equivalent to it.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import lombok.Builder;
import lombok.Data;
import lombok.NonNull;

@Data
@Builder
public class MyLoombok {

 @NonNull
 private final String attr1;

 @NonNull
 private final int attr2;
}


Generated code of builder.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import lombok.NonNull;

public class MyLoombok {

 @NonNull
 private final String attr1;

 @NonNull
 private final int attr2;

 @java.beans.ConstructorProperties({"attr1", "attr2"})
 MyLoombok(String attr1, int attr2) {
  this.attr1 = attr1;
  this.attr2 = attr2;
 }

 public static MyLoombokBuilder builder() {
  return new MyLoombokBuilder();
 }

 @NonNull
 public String getAttr1() {
  return this.attr1;
 }

 @NonNull
 public int getAttr2() {
  return this.attr2;
 }

 public boolean equals(Object o) {
  if (o == this) return true;
  if (!(o instanceof MyLoombok)) return false;
  final MyLoombok other = (MyLoombok) o;
  if (!other.canEqual((Object) this)) return false;
  final Object this$attr1 = this.getAttr1();
  final Object other$attr1 = other.getAttr1();
  if (this$attr1 == null ? other$attr1 != null : !this$attr1.equals(other$attr1)) return false;
  if (this.getAttr2() != other.getAttr2()) return false;
  return true;
 }

 public int hashCode() {
  final int PRIME = 59;
  int result = 1;
  final Object $attr1 = this.getAttr1();
  result = result * PRIME + ($attr1 == null ? 43 : $attr1.hashCode());
  result = result * PRIME + this.getAttr2();
  return result;
 }

 protected boolean canEqual(Object other) {
  return other instanceof MyLoombok;
 }

 public String toString() {
  return "singleclass.MyLoombok(attr1=" + this.getAttr1() + ", attr2=" + this.getAttr2() + ")";
 }

 public static class MyLoombokBuilder {
  private String attr1;
  private int attr2;

  MyLoombokBuilder() {
  }

  public MyLoombok.MyLoombokBuilder attr1(String attr1) {
   this.attr1 = attr1;
   return this;
  }

  public MyLoombok.MyLoombokBuilder attr2(int attr2) {
   this.attr2 = attr2;
   return this;
  }

  public MyLoombok build() {
   return new MyLoombok(attr1, attr2);
  }

  public String toString() {
   return "singleclass.MyLoombok.MyLoombokBuilder(attr1=" + this.attr1 + ", attr2=" + this.attr2 + ")";
  }
 }
}

Friday, 30 December 2016

This week 20/2016

DataNucleus Data Object  is one of JDO implementation. A performance of this implementation is 2 - 10 times slower then Hibernate (link to test).

Apache Isis - supports domain driven design by requirement of preparing model. Other things are generated and shared by configurable wicket GUI. 

EMF - Eclipse Modeling Framework - it is framework to defining and create model of data by eclipse modelling tools and then on basic of model there is generated Java code. 

JDepend - a tool which shows references between packages. Handy tool to check application design.

Classycle - similar tool to JDepend but additionally it allows to check references on class level as well.

Eclipse Metrics plugin - a eclipse plugin to check dependences between classes and cycles in packages.

Hibernate Search - A hibernate solution of full text searching using Apache Lucene engine. In my case I tried standard solution: single instance, standard indexing with result storage in files. I tried to change a language of analysed tokens but I couldn't find Polish dictionary.
Indexing is processed on request and can be executed as a blocking or asynchronous operation.


jMock - another test tool which allows to create mock. I used this tool in a few cases but the same I can do by Mockito. This tool has other order of processing than Mockito (given, when, then). JMock defines mocks and execution listeners then allows to execute tested method. After 4 hour I think, this tool is less flexible then Mockito but require less complex object to test. jMock couldn't create mock of class, it is possible only to mock interface and it is required to mock every used methods. In my cases it required more code and create instance of object - not mocks.

Saturday, 19 November 2016

This week 19/2016

This article is a summary of thoughts about implementing a piece of DDD in my application. This weekend I disinterred an old topic: How can I design something similar to the DDD in my application and don't turn over all existing application? How can I gently get into.
In inherited application there is strongly used hibernate. Entities model looks like it tries to build a full domain model - they have states and behaviours. However all functionalities use entities in view (and Session on view pattern) and it is difficult to do hermetic model especially then all entity attributes has public setters and getters.

My idea were:
  • to retrieves entities only to service level and then map them to immutable dto and dto use in views or if it was necessary map them to mutable Java Plain Object.
  • change access type for data in entitles. Till now there was property access an there was impossible to remove setter method from entity. I prefer field access. It is much more transparent and allow to remove getters and setters which can be implemented by Lombok library.
  • add new layer - application layer which collect a few independent functionalities and share them to controller.
  • I changed packaging of my classes. Classes were included to packages split in order: layer name, functionality. Now I package my classes in order: functionality, layer, but I still thinking about removing layer part of packages and much more granulate functionality.
  • reports contains data from many independent tables. I get data by native sql directly mapped to immutable dto.

Now I was focused on bounded domain model and how to resolve it in my application. In this application I should much more use CQRS pattern.


Anyway I think about some other implementation problems, ex. how should I implement JPA entities of bounded context? One context needs only a few attributes of all model, other needs some other but that attributes are archived in one db table.

I still looking for best solutions:)

Bellow I added a few interesting resources:

ddd series

ddd-in-practice

dddexample

domain-driven-design-with-java-ee-6

ddd-and-spring

Saturday, 12 November 2016

This week 18/2016

When I was at Devoxx 2016 conference, I chose one of DuyHai DOAN's presentation. I was late and I went at 15 minutes. It seemed that he was talking about some DSL framework so I was disappointed and bored. Lucky I tried to watch the presentation one more time and now I know that I didn't understand the context, the first 10 minutes was the most interesting.

However, to the point. Inspirited by DuyHai DOAN's presentation, I have interested in Annotation Processing. I found a good and clear article about this subject and all became easy.
But to the point. what is the Annotation Processing?
It is a phase of Java code compilation to byte code by javac. As you can see at picture bellow


http://openjdk.java.net/groups/compiler/doc/compilation-overview/javac-flow.png
at the beginning of compilation, the code is parsed and there is created a syntax's dictionary. Then there is executed the Annotation Processor which can read Java code or create new one. (There is assumption, the Annotation Processor can't modify existing code but there is some possibility. I will write about it later).
If the Annotation Processor creates new code, all cycle is repeated. If not, all code is analysed and translated to byte code. 

To study the Annotation Processor, I created 3 projects:
  • my annotation 
  • my implementation of the Annotation Processor 
  • some code in which I used my annotation.

Annotation: 
Notice a Retention Policy type.
@Retention(RetentionPolicy.SOURCE)
@Target({ ElementType.TYPE })
public @interface Getter {
}


Annotation Processor:
I created a file "javax.annotation.processing.Processor" in path "META-INF/services" and I put into it a path to implementation of my Annotation Processor 


@SupportedAnnotationTypes("test.annotationprocessor.annotation.Getter")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class GetterProcessor extends AbstractProcessor {

    public GetterProcessor() {
        super();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        createClassWithVelocityTemplate(roundEnv);
        return true;
    }

    public void createClassWithVelocityTemplate(RoundEnvironment roundEnv) {
        Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Getter.class);
        for (Element element : elements) {
            try {
                FileObject in_file = processingEnv.getFiler().getResource(StandardLocation.SOURCE_PATH, "", element.asType().toString().replace(".", "/") + ".java");

                CharSequence data = in_file.getCharContent(false);
                String data1 = addAFewMethods(data).toString();

                FileObject out_file = processingEnv.getFiler().createResource(StandardLocation.SOURCE_OUTPUT, "", element.asType().toString().replace(".", "/") + ".java");
                Writer w = out_file.openWriter();
                w.append(data1);

                velocityGeneration(w);
                w.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
....
    }
}
It reads a source of class with my annotation and create new class with additional code.


To be drawing subject to the end, it is good to mention in a nutshell: 

  1. Annotation Processing is supported by IDEs like Eclipse or IntelliJ. It is required to check this option in project settings.
  2. As I mentioned above, the Annotation Processor can read and create new code, however authors of Lombok library have found a bypass to this limit. Their library works as it could change a code. They modifies a syntax's dictionary and inject their code. 
  3. Javac doesn't use JVM but it is possible to debugging code in your IDE. When a debug option is added to execute command, javac shares an interface like JVM for remote connections.

Monday, 31 October 2016

This week 17/2016

SmartParam (v.1.1.2) is a powerful framework to parametrise an application.

1. Source of configuration
It is possible to load configuration from text file, database or create it dynamically.  Framework supports directly H2, MySql and Postgesql databases.


example of configuration file:

{
  name: "simpleCase",  inputLevels: 2,  cachable: true,  nullable: true,  arraySeparator: ";",
  levels: [
    {name: "registrationDate", type: "date",   matcher: "between/ie" },     
    {name: "name",                     type: "string" }, 
    {name: "value",                     type: "integer" }, 
    {name: "value2",                   type: "integer" }
  ]
}
registrationDate;name;value;value2
*: 2013-12-01;Adam;20*: 2013-12-01;Monia;5
 


2. Number of input/output parameters
At the beginning it is required to define structure of parameters:
  • name - name of configuration,
  • inputLevels - count of input parameters, which are used to wind exact output parameters,
  • nullable - by default it is false and if any rule match input parameters, it throws exception
  • levels - defines types of input and output parameters.
3. Supported parameters
Framework supports simple types of data, however it is possible to define your own type. There are two ways to do that: do converter or  type holder.
Type holder ex.
@ParamType("localdate")
public class LocalDateType implements Type<LocalDateHolder> {
.....
}
 
public class LocalDateHolder extends AbstractValueHolder {
    private final LocalDate date;
    public LocalDateHolder(LocalDate date) {
        this.date = date;    }
....
} 

4. Matcher
Framework provides all needed matchers but there is possible to create your own matcher.
ex.
@ParamMatcher("mymatcher")
public class MyMatcher implements Matcher {

    @Override    public <T extends ValueHolder> boolean matches(String s, String s1, Type<T> type) {

        return s.toString().equals(s1.toString());    }
}

One of useful matcher is BetweenMatcher. It supports defining a ranges of dates, numbers and defines default value by *

5. Other Notices
Framework presents itself great but project looks to be extinct.

Saturday, 22 October 2016

This week 16/2016

How works a synchronisation of some object in a nutshell.

My goal is to synchronise a block of code by some string which is a parameter of a function.

At the begging I wasn't sure how synchronisation mechanism works. Is it using equals and hash code to compare object or memory address where object is allocated.
So synchronisation doesn't use equal method but memory address where object is allocated to.

So how to synchronise part of code when I have many instances of the same object (ex. string)?

A solution is to use some container for synchronized objects and retrieves instance of  that object to use it to synchronization. In this case the best choose is map where it is possible to find object by key and get its value or if it not exists yet, add it.

So we need some kind of cache but how to manage this cache? We need only object instance when the synchronisation block is executed.
I think the easiest way on a single jvm is to use a weak reference. In this case I create a cache manager with WeakHashMap. The manager has a synchronized method findOrAdd and returns an instance of string object included to map.
What is important the WeakHashMap use weak reference only for key object so it is required to put as a value a WeakReference instance with my object.

Map map = new WeakHashMap();
map.put(myString, new WeakReference(myString));
Now, if instance of myString hasn't any reference to any other object or is not used to synchronisation, it will be removed from memory so removed from map as well.

Saturday, 2 July 2016

This week 9/2016

It pass a month since last post. I had a break because of my holidays and some other important things. Last week I was at Devoxx conference in Cracow. I'd like to write in a nutshell about some main topics.

1. What does Unsafe class and why there is some cry after it will miss?
Unsafe is a class in com.sun package. It was created for internal use of java classes but after some time it is used by common libraries. The Unsafe allow to manual managing memory usage, ex. creating table with greater index than allow int type. GC doesn't involve this part of memory.

2. Jdk8 - collections and lambda's expressions.
There was shown, how works lazy initialization and processing in collections. 
What gives us lambada expressions.

3. Next releases of Java. Architecture plans.
In Java 9 there is planned standardise an API. They plan to remove close 30 classes from com.sun package. The most problematic is Unsafe class. I mentioned about it role before.
Other main changes are:
- array index will be changed to long type,
- a generic class will save its type in bytecode. It will be possible overloading methods with generic collection.

4. Reactive programming - Rx.Java and Hysterix
Another time there was described Hysterix as a simple and excellent framework to maintenance microservices connections.

5. DDD and bounded domain context. One domain model is too huge and complicated to maintenance it. The best idea is to split it into subdomains connected with some context. Nobody shown a real code of that solution. I always asking me, how to do it with hibernate. Is it at all possible?

6. Angular JS 2
I didn't take a part in that sessions. Anyway sessions described how different is AngularJs 2 from AngularJs 1, pointed the way how to start. In a nutshell Angular 2 was totally changed. Now code is writing in typescript and than is compiled to javascript. As it could be noticed, it is totally other language.

7. Groovy - how to start and difference between syntax in Groovy and Java.
At first it is possible to change Java code file to groovy file and compile it. It will be working.  Groove is slower language, so is not recommended to use on production but it is very useful to create tests. It is possible to basic Java syntax and it will be working to. There is huge support for collections. Anyway last version of Groovy don't support lambda expressions from Java 8. But it is possible to code in Groovy and call Java classes and vice versa and then you can use lambda expressions in Java code. All details about language can be find on page http://groovy-lang.org/style-guide.html
One important notice. Sometimes the same code in Groovy could work otherwise than in Java.

8. JUnit 5 - futures


9. How to pass presentations. Good advice given by programmer for programmers.
Sławomir Sobótka was talking about causes of stage fright. He diagnosed that stage fright is caused by too high self-esteen and fright that it could be reduced.


10. Microservices