4th airhacks.fm Episode: "Micro Java EE"

4th episode "Micro Java EE" of airhacks.fm podcast with special guest, Payara CEO, Steve Millidge is available. We discussed Microservices, Cloud Native Java EE, Microprofile, EE4J, Thin WARs, Ueber JARS and Fat JARs.

Subscribe to airhacks.fm podcast via: RSS iTunes


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

From BeanShell and Kotlin over Deadlocked Conversations to AWS, Authentication and Java PWAs -- 45th airhacks.tv is available

From BeanShell over deadlocked conversations to AWS and authentication. The 45th airhacks.tv is available:

Any questions left? Ask now: https://gist.github.com/AdamBien/725f0e529bda54e2a35cf35c88f49c26 and get the answers at the next airhacks.tv.

See you at Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Serializing and Deserializing a POJO with LocalDate into JSON using JSON-B and Java EE 8

To serialize a POJO with JSON-B from Java EE 8 containing a java.time.LocalDate, you can either use the default format, or specify the serialization format with @JsonbDateFormat annotation:


import java.time.LocalDate;
import javax.json.bind.annotation.JsonbCreator;
import javax.json.bind.annotation.JsonbDateFormat;
import javax.json.bind.annotation.JsonbProperty;

public class Developer {

    public LocalDateTime birthdate;

    @JsonbDateFormat(value = "yyyy-MM-dd")
    public LocalDate firstHack;

    @JsonbCreator
    public Developer(
            @JsonbProperty("birthdate") LocalDateTime birthdate, 
            @JsonbProperty("firstHack") LocalDate firstHack) {
        this.birthdate = birthdate;
        this.firstHack = firstHack;
    }
}

Now the Developer can be serialized and deserialized with a javax.json.bind.Jsonb instance:


import java.time.LocalDate;
import java.time.Month;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;

public class DateSerializationTest {
    
    private Jsonb jsonb;
    
    @Before
    public void init() {
        this.jsonb = JsonbBuilder.
        newBuilder().
        build();
    }

    @Test
    public void serialize() {
        Developer developer = new Developer(LocalDateTime.of(1995, Month.MARCH, 12, 12, 42), 
                LocalDate.of(1998, Month.MARCH, 12));
        String serialized = this.jsonb.toJson(developer);
        System.out.println("serialized = " + serialized);
        assertThat(serialized, containsString("birthdate"));

    }

    @Test
    public void deserialize() {
        String deserialzed = " {\"birthdate\":\"1995-03-12T12:42:00\",\"firstHack\":\"1998-03-12\"}";
        Developer duke = this.jsonb.fromJson(deserialzed, Developer.class);
        assertThat(duke.birthdate.getYear(), is(1995));
    }

}

To run the example as JUnit test, you will need the following dependencies:


<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.json</artifactId>
    <version>1.1</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.eclipse</groupId>
    <artifactId>yasson</artifactId>
    <version>1.0</version>
    <scope>runtime</scope>
</dependency>

See you at Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

EM switching, BeanShell, Kotlin, JPA and JDBC, AWS, Authentication, XA, PWAs, SPAs and Java, JSON-B or the last airhacks.tv in 2017

Questions for the 45th, and very last, airhacks.tv show in 2017:

  1. About BeanShell
  2. Header parameters behind apache
  3. Switching between persistence units / EntityManager
  4. Thoughts on Kotlin
  5. Deadlocked conversations
  6. JPA and JDBC pooling
  7. Which AWS instance to take?
  8. Upgrading GlassFish without downtime
  9. Java EE 8 authentication and redirect / forward
  10. Dealing with complex components like tables in the "No Dependencies, Java EE-like" web development
  11. How to handle database connections in the clouds
  12. Two DBs with or without XA
  13. Java's answer to PWAs and SPAs
  14. CompletableFuture, JAX-RS and exception handling
  15. Form authentication and encryption
  16. JSON-B and LocalDateTime mapping
  17. JAX-WS, connection timeout, transaction timeout and dealing with rollbacks

Any questions left? Ask now, or wait a year.

Ask questions during the show via twitter mentioning me: http://twitter.com/AdamBien (@AdamBien) or using the hashtag: #airhacks or the live chat: http://www.ustream.tv/channel/adambien

See you at Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Monitoring Java EE Appservers with Prometheus and Grafana

Monitoring und visualising built-in Java EE metrics (payara.fish) with prometheus, grafana and a little help of a 16kB side car firehose:

See you at Java EE Microservices. Is Munich's airport too far? Learn from home: javaeemicro.services and Java EE Performance, Monitoring and Troubleshooting


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Java EE 8 on Java 9 - From Install to Deployment with OpenLiberty Server

Download, install, configure openliberty.io and deploy a sample Java EE 8 application with Java 9 features under 10 minutes with Maven:

See you at Java EE 8 on Java 9, at Munich Airport, Terminal 2


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Using Java 9 HTTP Client with JUnit and Maven

Java 9 comes with built-in HTTP (2) client (incubator status):


import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.time.Duration;
import jdk.incubator.http.HttpClient;
import jdk.incubator.http.HttpRequest;
import jdk.incubator.http.HttpResponse;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Test;

public class HttpClientTest {

    private HttpClient client;

    @Before
    public void init() {
        this.client = HttpClient.newHttpClient();
    }

    @Test
    public void get() throws IOException, InterruptedException {
        URI uri = URI.create("http://airhacks.com");
        HttpRequest getRequest = HttpRequest.newBuilder(uri).
                GET().
                timeout(Duration.ofMillis(500)).
                build();
        HttpResponse<String> response = this.client.send(getRequest,
                HttpResponse.BodyHandler.asString(Charset.defaultCharset()));
        String payload = response.body();
        assertThat(payload, containsString("java"));
    }
}

The HTTP client resides in jdk.incubator.httpclient module and has to be "required". The module-info.java resides in src/main/java:

module com.airhacks.http {
    requires jdk.incubator.httpclient;
}

You will need the maven-compiler-plugin at least in the version > 3.6.1


<build>
<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.7.0</version>
    </plugin>
</plugins>
</build>    

Now the unit tests compiles, but the execution fails with:


java.lang.NoClassDefFoundError: Ljdk/incubator/http/HttpClient;
    at java.base/java.lang.Class.getDeclaredFields0(Native Method)
    at java.base/java.lang.Class.privateGetDeclaredFields(Class.java:3024)
    at java.base/java.lang.Class.getDeclaredFields(Class.java:2205)    

Although the module is declared, it has to be still added with the following JVM argument:


<properties>
    <argLine>--add-modules jdk.incubator.httpclient</argLine>
(...)
</properties>
See you at Java EE 8 on Java 9, at Munich Airport, Terminal 2


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Time travelling with Bean Validation 2.0 and Java EE 8

With Java EE 8 and Bean Validation 2.0 JSR-380 you can time travel by passing an adjusted java.time.Clock instance to the clockProvider method:


import java.time.Clock;
import java.time.Duration;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
(...)

public class BeanValidationTest {

private Validator validator;

@Before
public void init() {
    ValidatorFactory factory = Validation
            .byDefaultProvider()
            .configure()
            .clockProvider(this::configureClockWithFutureTime)
            .buildValidatorFactory();
    this.validator = factory.getValidator();
}

Clock configureClockWithFutureTime() {
    return Clock.offset(Clock.systemDefaultZone(), Duration.ofSeconds(10));
}


Now you can configure whether your vacations are already over:

        
import java.util.Date;
import javax.validation.constraints.PastOrPresent;

public class Vacations {

    @PastOrPresent
    private Date date;

    public Vacations() {
        this.date = new Date();
    }
}


@Test
public void vacationsAreOver() {
    Set<ConstraintViolation<Vacations>> violations = this.validator.validate(new Vacations());
    assertTrue(violations.isEmpty());
}

...or whether you have to work again:


import java.util.Date;
import javax.validation.constraints.Future;

public class Development {

    @Future
    private Date date;
    public Development() {
        this.date = new Date();
    }
}
//....
@Test
public void weAreWorkingNow() {
    Set<ConstraintViolation<Development>> violations = this.validator.validate(new Development());
    boolean rightMessage = violations.stream().
            map(violation -> violation.getMessage()).
            allMatch(message -> "must be a future date".equalsIgnoreCase(message));
    assertTrue(rightMessage);
    assertFalse(violations.isEmpty());
}

}

To run the bean validation as a JUnit test, you will need the following dependencies:


<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.5.Final</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <version>3.0.0</version>
    <scope>test</scope>
</dependency>

See you at Java EE 8 on Java 9, at Munich Airport, Terminal 2


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Java 9 orTimeout and JAX-RS AsyncResponse

Java 9 introduced the CompletableFuture#orTimeout method which allows the configuration of a "per pipeline" timeout. In case there are multpiple pipelines involved to answer a single request, the JAX-RS AsyncResponse#setTimeout method can be used to set the max duration (see it in action: javaeemicro.services) for the entire request:


import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.Response;

@Path("ping")
public class PingResource {

    @GET
    public void ping(@Suspended AsyncResponse response) {

        CompletableFuture.supplyAsync(this::answer).
                thenAccept(response::resume).
                orTimeout(100, TimeUnit.MILLISECONDS).
                exceptionally((t) -> handleTimeout(response::resume, t));


    }

    Void handleTimeout(Consumer<Response> consumer, Throwable t) {
        consumer.accept(Response.status(503).
                header("cause", "timeout in the pipeline").
                header("exception", t.toString()).
                build());
        return null;
    }

    public String answer() {
        try {
            Thread.sleep(200);
            return "42 + " + System.currentTimeMillis();
        } catch (InterruptedException ex) {
            throw new IllegalStateException("cannot sleep");
        }
    }
}    

The request: curl -i [...]/ping outputs:


HTTP/1.1 503 Service Unavailable
X-Powered-By: Servlet/4.0
cause: timeout in the pipeline
exception: java.util.concurrent.TimeoutException
Date: Fri, 01 Dec 2017 06:25:32 GMT
Content-Length: 0
Content-Language: en-DE
Connection: Close

See you at Java EE 8 on Java 9, at Munich Airport, Terminal 2


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

From JDK 1.0 over CORBA, RPC, REST over Java EE to Cloudnative and Back

From early Java (JDK 1.0), over CORBA, serverside Java, WebSphere, openliberty.io, heavyweight J2EE and lightweight Java EE and back. About the meaning of "cloudnative" and why footprint and size matter.

A conversation with an ebullient hacker ebullientworks / @ebullientworks: subscribe to airhacks.fm podcast via: RSS or iTunes


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

realworldpatterns.com
Online Workshops
...the last 150 posts
...the last 10 comments
License