Skip to main content
  1. Tags/

Java

2025

Short links, clear architecture – A URL shortener in Core Java

A URL shortener seems harmless – but if implemented incorrectly, it opens the door to phishing, enumeration, and data leakage. In this first part, I’ll explore the theoretical and security-relevant fundamentals of a URL shortener in Java – without any frameworks, but with a focus on entropy, collision tolerance, rate limiting, validity logic, and digital responsibility. The second part covers the complete implementation: modular, transparent, and as secure as possible.

If hashCode() lies and equals() is helpless

A deep look into Java’s HashMap traps – visually demonstrated with Vaadin Flow. The silent danger in the standard library # The use of HashMap and HashSet is a common practice in everyday Java development. These data structures offer excellent performance for lookup and insert operations, as long as their fundamental assumptions are met. One of them is hashCode() of a key remains stable. But what if that’s not the case?

Creating a simple file upload/download application with Vaadin Flow

Vaadin Flow is a robust framework for building modern web applications in Java, where all UI logic is implemented on the server side. In this blog post, we’ll make a simple file management application step by step that allows users to upload files, save them to the server, and download them again when needed. This is a great way to demonstrate how to build protection against CWE-22, CWE-377, and CWE-778 step by step.

Open-hearted bytecode: Java Instrumentation API

What is the Java Instrumentation API? # The Java Instrumentation API is part of the java.lang.instrument package and allows you to change or analyse class bytecode at runtime. It is particularly intended for the development of profilers, agents, monitoring tools, or even dynamic security mechanisms that need to intervene deeply in a Java application’s behaviour without changing the source code itself.

Synchronous in Chaos: How Parallel Collectors Bring Order to Java Streams

Sometimes it’s not enough for something to work - it has to work under load. In modern applications that process large amounts of data, the Streams API in Java provides developers with an elegant, declarative tool to transform, filter, and aggregate data in pipelines. ​​Describing complex data operations with just a few lines is seductive and realistic. But what happens when these operations encounter millions of entries? When should execution be done in multiple threads in parallel to save time and effectively use multi-core systems?

Rethinking Java Streams: Gatherer for more control and parallelism

Since version 8, Java has introduced an elegant, functional approach to processing data sets with the Streams API. The terminal operation collect(…) represents the bridge from the stream to a targeted aggregation - in the form of lists, maps, strings or more complex data structures. Until Java 20 the processing was done Collector-Instances were regulated, which internally consisted of a supplier, an accumulator, a combiner and optionally a finisher. This model works well for simple accumulations but has noticeable limitations, particularly for complex, stateful, or conditional aggregations.

From Java 8 to 24: The evolution of the Streams API

·23 mins
The introduction of the Stream API in Java marked a crucial step in the development of functional programming paradigms within the language. With Java 24, stream processing has been further consolidated and is now a central tool for declarative data processing Stream not about an alternative form of Collection, but rather an abstract concept that describes a potentially infinite sequence of data that is transformed and consumed through a pipeline of operations. While a Collection is a data structure that stores data, Stream is a carrier of a computing model: It does not store any data but instead allows the description of data flows.

2024

TornadoVM - Boosting the Concurrency

TornadoVM is an open-source framework that extends the Java Virtual Machine (JVM) to support hardware accelerators such as Graphics Processing Units (GPUs), Field-Programmable Gate Arrays (FPGAs), and multi-core central processing units (CPUs). This allows developers to accelerate their Java programs on heterogeneous hardware without needing to rewrite their code in low-level languages such as CUDA or OpenCL.

JUnit annotations in focus: The connection between @Test and @Testable

The annotations @Test and @Testable have played an important role in the Java ecosystem regarding application testing. They are essential tools that help developers make unit and automated testing more effective. In this paper, we will explore the differences and connections between @Test and @Testable analyze and the motivation behind the introduction of @Testable understand. We will also play the role of @Testable in developing your test engines and discuss their importance for the flexibility and expandability of tests.

The Risks of Mocking Frameworks: How Too Much Mocking Leads to Unrealistic Tests

·10 mins
Extensive use of mocking frameworks such as Mockito in software development can lead to unrealistic tests. This is because mocking frameworks simulate dependencies of classes or methods in order to test them in isolation. However, when too many mock objects are used, the test often loses touch with reality, which can affect the validity and reliability of the tests. It is important to use mocking carefully to find the right balance between isolated testing and realistic simulation.