Free Video Series -- Cloud Native Java EE on OpenShift

In the free, 3-part "Cloud-native Java EE" video series, I'm covering Java microservices, containers, openshift, WildFly full, container packaging, S2I, Java EE, patterns, errorhandling, scaling, packaging, configuration, deployment, with nothing but ThinWARs. Lightning fast deployments included.

Series preview (all episodes):

The code is simple enough, so no slides were necessary to illustrate the ideas.

See you at Web, MicroProfile and 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 Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.

Airport MUC workshops: Web (SPA, PWAs, Offline, Desktop, Mobile) Applications Essentials and Effective Web Applications. No migrations. #usetheplatform

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

A possible cause of "...has been blocked by CORS policy"

A JavaScript client:


const deletePing = async () => {
    const config = {
        method: "delete"
    };
    const response = await fetch('http://localhost:8080/cors-error-delete/resources/ping/duke', config);
    console.log(response.status);
};
deletePing();

reports the following error:
app.js:6 OPTIONS http://localhost:8080/cors-error-delete/resources/ping/duke and Access to fetch at 'http://localhost:8080/cors-error-delete/resources/ping/duke' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
when a preflight request automatically initiated by the browser fails with status 404.

This will happen, if a resource like:


import javax.ws.rs.DELETE;
import javax.ws.rs.Path;

@Path("ping")
public class PingResource {

    @DELETE
    public void remove() {
    }
}

exposed with:

@ApplicationPath("resources")
public class JAXRSConfiguration extends Application {}    
and with installed CORS-filter:

<dependency>
    <groupId>com.airhacks</groupId>
    <artifactId>jaxrs-cors</artifactId>
    <version>0.0.2</version>
</dependency>    

doesn't accept path params, but the JavaScript client passes them.

In our case: DELETE http://localhost:8080/cors-error-delete/resources/ping/duke is requested, but only http://localhost:8080/cors-error-delete/resources/ping/ is offered.

See you at Web, MicroProfile and 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 Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.

Airport MUC workshops: Web (SPA, PWAs, Offline, Desktop, Mobile) Applications Essentials and Effective Web Applications. No migrations. #usetheplatform

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Java EE 8 Authentication and Authorization -- a Podcast Episode with Arjan Tijms

Subscribe to airhacks.fm podcast via: RSS iTunes

An airhacks.fm conversation with Arjan (@arjan_tijms) about:

"Starting programming with Commodore 64, blog interview about zeef, "Programming in Basic" with the age of 7, Phillips P2000, Simons Basic, Assembly on Commodore 64, defaulting to C, weird main function in C, developing a database to maintain Judo progress and expenses, being a CEO of a kid organization to sell goods on free markets with other kids, SGI Indy, helping sister with recursion in Java, advertisements on websites with awin startup, OrionServer, Java Servlet Development Kit (JSDK) 1.0, Sun One Application Server, Trifork Application Server, Java EE is like operating system for business components, counting cycles for method invocations, From OrionServer to Tomcat, 3 views per server in a 2-3 node cluster, cutting libraries by moving from Tomcat to JBoss in 2 weeks, zanox.de buys awin, discussion about polyglot programming, parsing gigabytes of XML, founding Zeef.com with ten developers, monatenization challenges, starting as tech lead at Payara, JASPIC, JAAS, JACC, from form login to authenticated and authorised user, the relation between JAAS and JAAC, JAAS is about code security and code trust, in JAAC the code is trusted and the user is not trusted, JASPIC is the authentication mechanism, Java EE 8 security is the syntactic sugar around existing security specs, the simplest possible authentication with JSR-375 / Java EE 8 Security, IdentityStores vs. Realm, basic authentication and realm clarification, IdentityStore was missing in Java EE, the whole JSR-375 spec is about 12 classes, the difference between security group and roles, 1:1 role to group mapping is default in Java EE 8."

Arjan's blog, Arjan on omnifaces blog and @omnifaces.


NEW: Online Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.

Airport MUC workshops: Web (SPA, PWAs, Offline, Desktop, Mobile) Applications Essentials and Effective Web Applications. No migrations. #usetheplatform

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Java is #1 in January 2019

Java is #1 (16.904%, +2.69%), C is #2 (13.337%, +2.30%) and Python is #3 (8.294%, +3.62%).

The most popular JVM-based language is Groovy with #21 and 1.016% [Source: TIOBE Index for January]

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 Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.

Airport MUC workshops: Web (SPA, PWAs, Offline, Desktop, Mobile) Applications Essentials and Effective Web Applications. No migrations. #usetheplatform

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Generating a Test Client for HTTP/JSON (JAX-RS / JSON-B) Services

In this screencast I'm creating a Java EE 8 project from scratch using an archetype, expose a HTTP / JSON service with JAX-RS and JSON-B, build the project WAD using Apache Maven and deploy 4.2kB WAR to openliberty (the largest possible installation with all Java EE 8 + MicroProfile features enabled) in 4 mins:

See you at Web, MicroProfile and Java EE Workshops at MUC Airport, particularly at the Java EE CI/CD, Testing and Quality workshop


NEW: Online Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.

Airport MUC workshops: Web (SPA, PWAs, Offline, Desktop, Mobile) Applications Essentials and Effective Web Applications. No migrations. #usetheplatform

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

2018 Predictions Review, Streaming JMS to DB, JPA Refresh, WebComponents and Java EE 8--58th airhacks.tv

In the first episode of 2019, we covered the following topics:

"Watch and Deploy (WAD) demo, 2018 Predictions Review, Streaming JMS to DB, Message parallelism, JPA Refresh, WebComponents and Java EE 8, Async Script Loading"

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

See you at Web, MicroProfile and 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 Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.

Airport MUC workshops: Web (SPA, PWAs, Offline, Desktop, Mobile) Applications Essentials and Effective Web Applications. No migrations. #usetheplatform

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Illegal base64 character 5f, Illegal base64 character 2d and java.util.Base64

Decoding a String with invalid Base64 '_' character:


import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.junit.jupiter.api.Test;

public class Base64EncodeTest {

    @Test
    public void decodeUnderscode() {
        byte[] bytes = "CAFEHELLO_BABEDUKE".getBytes(StandardCharsets.UTF_8);
        Base64.getDecoder().decode(bytes);
    }
}

raises the java.lang.IllegalArgumentException: Illegal base64 character 5f

and the character '-':

@Test
public void decodeMinus() {
    byte[] bytes = "CAFEHELLO-BABEDUKE".getBytes(StandardCharsets.UTF_8);
    Base64.getDecoder().decode(bytes);
}    

...leads to: java.lang.IllegalArgumentException: Illegal base64 character 2d

Both characters can be decoded with Base64.getUrlDecoder:


@Test
public void urlDecode() {
    byte[] underscored = "CAFEHELLO_BABEDUKE".getBytes(StandardCharsets.UTF_8);
    Base64.getUrlDecoder().decode(underscored);

    byte[] dashed = "CAFEHELLO-BABEDUKE".getBytes(StandardCharsets.UTF_8);
    Base64.getUrlDecoder().decode(dashed);

}    
See you at Web, MicroProfile and 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 Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.

Airport MUC workshops: Web (SPA, PWAs, Offline, Desktop, Mobile) Applications Essentials and Effective Web Applications. No migrations. #usetheplatform

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

List to JsonArray Conversion with JSON-P and Java EE 8

List<String> can be converted into JsonArray with:



import javax.json.Json;
import javax.json.JsonArray;
import javax.json.stream.JsonCollectors;
import org.junit.jupiter.api.Test;

public class StringListToJsonArrayTest {

    @Test
    public void conversion() {
        
        JsonArray jsonStringArray = Arrays.asList("duke", "duchess").
                stream().
                map(Json::createValue).
                collect(JsonCollectors.toJsonArray());
                        
        System.out.println(jsonStringArray);
    }
}    

...and the result is: ["duke","duchess"]

See you at Web, MicroProfile and 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 Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.

Airport MUC workshops: Web (SPA, PWAs, Offline, Desktop, Mobile) Applications Essentials and Effective Web Applications. No migrations. #usetheplatform

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Creating Domain-Specific Metrics On-The-Fly with MicroProfile

Domain-specific counters can be created on-the-fly by injecting the MetricRegistry:


import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.annotation.RegistryType;    

@Path("ping")
public class PingResource {
    
    @Inject
    @RegistryType(type = MetricRegistry.Type.APPLICATION)
    MetricRegistry registry;

    @GET
    public String ping() {
        registry.counter("pingCount").inc();
        return "Enjoy Java EE 8 with MicroProfile ThinWARs!";
    }
}    

curl http://localhost:9080/metrics/application yields:

# TYPE application:ping_count counter
application:ping_count 1    
    
and curl -H"Accept: application/json" http://localhost:9080/metrics/application returns

{"pingCount":1}    
    

The size of the WAR is 4kB. Initial build time: 3292 ms, subsequent build times: < 3s. Deploy time: 0.233 seconds.

Built and deployed with WAD and tested with openliberty (the largest possible installation with all Java EE 8 + MicroProfile features enabled).

See you at Web, MicroProfile and 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 Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.

Airport MUC workshops: Web (SPA, PWAs, Offline, Desktop, Mobile) Applications Essentials and Effective Web Applications. No migrations. #usetheplatform

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Asynchronous BulkHeads with Fallback and MicroProfile

The org.eclipse.microprofile.faulttolerance.Asynchronous annotation together with org.eclipse.microprofile.faulttolerance.Bulkhead introduces a configurable and monitorable thread pool "on-the-fly":


import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Consumer;
import org.eclipse.microprofile.faulttolerance.Asynchronous;
import org.eclipse.microprofile.faulttolerance.Bulkhead;
import org.eclipse.microprofile.faulttolerance.Fallback;
import org.eclipse.microprofile.metrics.annotation.Counted;
    
    
public class AsynchronousCalculator {

    @Counted
    @Asynchronous
    @Fallback(fallbackMethod = "onOverload")
    @Bulkhead(value = 2, waitingTaskQueue = 10)
    public Future intenseCalculation(Consumer resultListener) {
        int computation = 2 * 21;
        resultListener.accept(computation);
        return CompletableFuture.completedFuture(null);
    }

    /**
    * onOverload is called on overload :-)
    */
    public Future onOverload(Consumer resultListener) {
        System.out.println("Please call me next time later");
        resultListener.accept(13);
        return CompletableFuture.completedFuture(null);

    }
}    

The fully optional org.eclipse.microprofile.metrics.annotation.Counted annotation causes the application server to emit the metric: "application:com_airhacks_asynchronous_control_asynchronous_calculator_intense_calculation 15" which reflects the current number of instances and so the number of parallel processes (in this example 15) at the same time.

On top of that also Bulkhead metrics and fallback counters are emitted (excerpt):


# TYPE (...)_calculator_intense_calculation_fallback_calls_total counter
(...)_calculator_intense_calculation_fallback_calls_total 0
# TYPE (...)_calculator_intense_calculation_bulkhead_execution_duration_mean_seconds gauge
(...)_calculator_intense_calculation_bulkhead_execution_duration_mean_seconds 1.00234796556958
# TYPE (...)_calculator_intense_calculation_bulkhead_execution_duration_max_seconds gauge
(...)_calculator_intense_calculation_bulkhead_execution_duration_max_seconds 1.007435808
# TYPE (...)_calculator_intense_calculation_bulkhead_execution_duration_min_seconds gauge
(...)_calculator_intense_calculation_bulkhead_execution_duration_min_seconds 1.0000803550000001
# TYPE (...)_calculator_intense_calculation_bulkhead_execution_duration_stddev_seconds gauge
(...)_calculator_intense_calculation_bulkhead_execution_duration_stddev_seconds 0.0016244590722208272
# TYPE (...)_calculator_intense_calculation_bulkhead_execution_duration_seconds summary
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds_count 2370
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.5"} 1.002190041
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.75"} 1.003775723
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.95"} 1.0051155980000002
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.98"} 1.005298392
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.99"} 1.005314287
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.999"} 1.006405762
# TYPE (...)_calculator_intense_calculation_bulkhead_calls_accepted_total counter
(...)_calculator_intense_calculation_bulkhead_calls_accepted_total 2400
(...)    

The @Asynchronous methods can be easily combined with asynchronous JAX-RS resources:


@RequestScoped
@Produces(MediaType.TEXT_PLAIN)
@Path("calculations")
public class CalculationsResource {

    @Inject
    AsynchronousCalculator worker;

    @GET
    public void ping(@Suspended AsyncResponse response) {
        worker.intenseCalculation(response::resume);
    }
}

The size of the WAR is 6kB. Build time: 2986 ms, deploy time: 0.233 seconds. Built and deployed with WAD and tested with openliberty (the largest possible installation with all Java EE 8 + MicroProfile features enabled).

The general availability of MicroProfile on all major application servers makes the Porcupine superfluous and your WARs a few KB thinner.

See you at Web, MicroProfile and 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 Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.

Airport MUC workshops: Web (SPA, PWAs, Offline, Desktop, Mobile) Applications Essentials and Effective Web Applications. No migrations. #usetheplatform

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

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