kcctl--The Missing Kafka Connect Command Line Interface (CLI)

kcctl is the missing Command Line Interface (CLI) for kafka connect implementations like e.g. debezium. kcctl is a fast and convenient Connect REST Interface wrapper, completely written in Java:

Regular Expressions With Java's Text Blocks / Multiline Strings

A Java regex pattern "java or duke" matches on a regular Java string:

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.regex.Pattern;

import org.junit.jupiter.api.Test;

public class RegexTest {

    public void singleLine(){
        var pattern = Pattern.compile(".*(java|duke).*");
        var text = "java duke";

...but fails on multiline Java String / Text Blocks:

public void multiLine() {
    var pattern = Pattern.compile(".*(java|duke).*");
    var message = """

The option Pattern.DOTALL:

(...) In dotall mode, the expression . matches any character, including a line terminator. By default this expression does not match line terminators (...)

makes the regular expression work on multiline strings:

public void multiLineDotAll() {
    var pattern = Pattern.compile(".*(java|duke).*",Pattern.DOTALL);
    var message = """

MicroProfile 5.0--an airhacks.fm podcast

Subscribe to airhacks.fm podcast via: spotify| iTunes| RSS

The #173 airhacks.fm episode with Emily Jiang (@emilyfhjiang) about:
MicroProfile 4.0, 5.0, MicroProfile relation to Jakarta EE, the MicroProfile book, metrics, OpenTelemetry, APIs, shims, SPIs and some ideas for the future
is available for

Web Components, Boundary Control Entity (BCE) and Unidirectional Data Flow with redux

Web Components are supported by all major browsers (https://caniuse.com/custom-elementsv1) and therefore do not require any additional shims or polyfills. Custom Elements combined with modern JavaScript versions (ES 6+) already provide a Java-like "look and feel":

class JavaDev extends HTMLElement {
    connectedCallback() {
        const message = "Web Components"
        this.innerHTML = `Hello, ${message}`;

However, the "vanilla" Web Component approach would require a complete re-rendering of the entire element and will result in slower performance in more sophisticated applications. Because we are setting a raw string, which can also contain user input and data fetched from a server, the above approach also comes with a security risk. Thankfully, JavaScript provides a way to declare functions "tagged templates" (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates), which process the raw String and can realize a faster or more secure rendering.

A tagged template function receives the entire String with all "bindings," which allows the implementation of additional syntactic sugar. lit-html is an example of such implementation, which optimizes the rendering, escapes JavaScript code, and adds convenient event handlers' attachment:

const template = html`
<button @click="${_ => this.newBookmark()}">new bookmark</button>

Vanilla Web Components combined with plain lit-html templating "function" already feel like a lean and productive JavaScript framework. With lit-html, you are already good to go for smaller web applications. Applications with many interacting components will require a state management solution. Without a central "mediator" (https://en.wikipedia.org/wiki/Mediator_pattern), the individual Custom Elements will have to communicate with each other directly.

Redux (https://redux.js.org) is a lean (single file) implementation of the "mediator" pattern. It is a central singleton that manages the entire state of the application and notifies all listeners about the changes. The Redux library's use may lead to a significant boilerplate, but it integrates well with lit-html and Web Components. Web Components combined with lit-html, redux, and a few conventions are productive and scale for more complex, interactive applications.

The "Boundary Control Entity" is one of the oldest architectural patterns (https://en.wikipedia.org/wiki/Entity-control-boundary), is similar to MVC, and even provides icons available in all popular design and sketching tools. Equipped with BCE, you don't have to argue about the naming conventions, can conveniently ignore the "Parkinson's law of triviality" (https://en.wikipedia.org/wiki/Law_of_triviality), and focus on the semantics instead.

A complex application is divided into functional, feature-driven folders named after essential concepts. Each such folder comprises at most the following directories:
  • Boundary: contains the views implemented with Custom Elements ("Web Components"). The custom elements react to user input and forward the extracted, relevant data to the "controls." All views are listening to redux store changes and are re-rendered at any state mutation.
  • Control: are the glue between the visual views and the redux "store." A control package contains functions that implement business logic and backend communication. Controls are asynchronous, "fire-and-forget" functions that process the user input, call external services, and dispatch the data as "redux actions" to the store.
  • Entity: the entity folder contains reducers that mutate the state. Any state change leads to notification of all listeners. Maintaining object lists, filtering, or changing the state are the typical responsibilities of functions residing in the "entity" package.

Combining vanilla Web Components with lit-html and redux comes with the following advantage:

  1. You can start with Web Components without learning any additional framework. Web Components are built-in into the browser, they are well documented, stable, and not expected to change. Migrations or upgrades are not necessary--you only have to learn them once and never migrate.
  2. lit-html and redux are small utilities with several alternatives available.
  3. BCE comes with a clear and consistent structure, which scales for large frontends.
  4. The combination of Web Components, lit-html, and redux toolkit leads to code similar to React without any framework involved.
  5. The necessary tooling is minimal. No transpilations, build tools, or bundling is required. Only a simple web server with hot-reload functionality like, e.g., https://browsersync.io, is recommended.
Standards APIs like, e.g., Web Components are already backed into the browser. Therefore using a JavaScript framework requires a significant added value to replace an already existing API. Over time JavaScript frameworks become less and less relevant. Even today, you can implement complex web applications with a low-magic approach. SpaceX engineers already recognized the productive mix of Web Components, CSS, and JavaScript: "We are the SpaceX software team, ask us anything!"

Check the following quickstarter, just "git clone && go." https://github.com/adambien/bce.design

See the BCE quickstarter in action:

2021 in review, EDAs, EJB to CDI, JPA, Logging, DDOS, AWS, Asynchronous Processing, Obfuscation, MicroProfile and JDBC--95th airhacks.tv

The first airhacks.tv in 2021, live streamed from youtube.com/c/bienadam with the following topics:

2021 in review, killer use cases for Event Driven Architectures, EJB 2 to EJB 3 and EJB to CDI migrations, JPA alternatives, dynamic log configuration, DDOS prevention on AWS Lambda and AWS Fargate, Asynchronous Processing, JavaScript obfuscation, HTTP PATCH and Java 17, GlassFish vs. Payara, MicroProfile and JDBC
See you every first Monday of the month at https://airhacks.tv 8pm CET (UTC+1:00). Show is also announced at: meetup.com/airhacks.

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

Formatting String Lists with Collector#joining, Prefix and Suffix

The method Collector#joining is overloaded with the parameters CharSequence prefix, CharSequence suffix which make List formatting easier:

import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;

public class CollectorsJoiningTest {

    public void withPrefixAndSuffix() {
        var words = List.of("java","duke","jvm");
        var message = words.stream().collect(Collectors.joining(",", "[", "]"));

The unit test prints: [java,duke,jvm]

2021 in review, EDAs, EJB to CDI, JPA, Logging, DDOS, AWS, Asynchronous Processing, Obfuscation, MicroProfile and JDBC--or Topics for the 2022.1 airhacks.tv

Questions and topics https://gist.github.com/AdamBien/2578630397cdab8f07e811627240fa5f for the 94th airhacks.tv live stream on youtube.com/c/bienadam/live:

  1. 2021 in review
  2. Event stores, event driven architectures, traditional CRUD and 2022 predictions
  3. Migrating from EJB to CDI
  4. Circular dependencies, bundling with JavaScript
  5. JPA AttributeConverters and RequestScoped
  6. Dynamically changing log level
  7. DDOS prevention in the AWS clouds
  8. Private vs. public clouds
  9. Asynchronous processing, sessions and concurrency
  10. Obfuscating JavaScript code
  11. HTTP Patch and Java 17
  12. MicroProfile and JDBC-based persistence
See you every first Monday of the month at airhacks.tv 8pm CET (UTC+1:00). Show is also announced at: meetup.com/airhacks.

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

Object Mapping Observations and the Deprecated Dozer

In 2013 I wrote a post: "In Case Dozer Or BeanUtils Are Working Well You Have A Problem." Most projects back then copied identical object hierarchies, usually persistent JPA entities and transient Data Transfer Objects, back and forth with the decoupling as the primary goal.

Object copying was intended to act as design insurance: potential JPA / persistence layer changes don't have to be visible in the data transfer layer. Since 2013 I have had the chance to review some of the "object copying" projects and noticed the lack of such incompatible changes. In the vast majority of all cases, identical objects are still copied back and forth. Dozer is not an invasive framework, but at least requires the usage of the org.dozer.Mapper. Depending on the design, there can be hundreds of such dependencies. Dozer is deprecated. You will find the following notice on https://github.com/DozerMapper/dozer (6.5.2):
"The project is currently not active and will more than likely be deprecated in the future. If you are looking to use Dozer on a greenfield project, we would discourage that."

Dozer suggest the use of mapstruct or modelmapper frameworks instead.

However, consider removing any superfluous 1:1 mapping logic altogether before migrating dozer to another mapping framework. With Java Records, JSON-P, or Java Records and JSON-B you get interesting out-of-the-box alternatives to an external library and so dependency.

How jClarity Happened--an airhacks.fm podcast

Subscribe to airhacks.fm podcast via: spotify| iTunes| RSS

The #172 airhacks.fm episode with Martijn Verburg (@karianna) about:
Java, performance optimization, the jClarity startup, performance optimizations with AI, and Java at Microsoft
is available for

Creating Executable Java "Scripts" with an Executable Java "Script"

The following Java "script" converts the src/main/java/airhacks/App.java script into an executable "Single-File Source-Code Program"

#!/usr/bin/java --source 17
import java.nio.file.Path;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;

public class CreateJavaScript {

    public static void main(String ...args) throws IOException{
        var scriptDeclaration = "#!/usr/bin/java --source 17";
        var inputFile = Path.of("src/main/java/airhacks/App.java");
        var outputFile = Path.of("target","App.sh");

        var content = Files.readString(inputFile);
        var contentWithDeclaration = """
        """.replace("$declaration", scriptDeclaration)
            .replace("$content", content);

This Java "script" ships with Maven Java 17 Quickstarter: https://github.com/AdamBien/java17-plain

Online Workshops
...the last 150 posts
...the last 10 comments