Archive for the ‘General’ Category
[PHPForumParis2023] PhpStorm = <3 – Charles Desneuf
At Forum PHP 2023, Charles Desneuf, a freelance developer, architect, and tech coach, delivered an enthusiastic exploration of PhpStorm, an integrated development environment (IDE) that he credits with transforming his coding experience. With a blend of technical insight and genuine passion, Charles shared how PhpStorm enhances productivity and brings joy to development workflows. His talk, rich with practical demonstrations, highlighted the IDE’s features, from automated testing to live templates, inspiring PHP developers to optimize their tools for efficiency and creativity.
Enhancing Productivity with PhpStorm
Charles opened by emphasizing PhpStorm’s role in boosting developer productivity. He described how the IDE’s robust features, such as intelligent code completion and real-time error detection, allow developers to write and modify code with confidence. Charles demonstrated how PhpStorm’s integration with testing frameworks enables seamless execution of unit tests directly within the IDE, streamlining workflows. By sharing his personal journey, he underscored how these tools eliminate friction, allowing developers to focus on crafting high-quality PHP applications.
The Joy of Playful Coding
Beyond efficiency, Charles highlighted the playful aspect of using PhpStorm, likening coding to a game. He showcased live templates, which enable developers to create reusable code snippets, significantly speeding up repetitive tasks. For example, Charles illustrated how a custom template could generate a test method with a few keystrokes, transforming mundane tasks into engaging challenges. His infectious enthusiasm encouraged attendees to explore PhpStorm’s features creatively, fostering a sense of enjoyment in their daily work.
Practical Applications and Community Sharing
Charles concluded by encouraging developers to experiment with PhpStorm’s features, such as automated refactoring and test integration, to enhance their workflows. He shared a personal website where he distributes his live templates, inviting the community to contribute their own. This collaborative spirit, combined with his call to action for developers to reflect on their tool usage, inspired attendees to adopt PhpStorm or optimize their existing setups, ensuring both productivity and satisfaction in their coding endeavors.
[DevoxxBE2023] Making Your @Beans Intelligent: Spring AI Innovations
At DevoxxBE2023, Dr. Mark Pollack delivered an insightful presentation on integrating artificial intelligence into Java applications using Spring AI, a project inspired by advancements in AI frameworks like LangChain and LlamaIndex. Mark, a seasoned Spring developer since 2003 and leader of the Spring Data project, explored how Java developers can harness pre-trained AI models to create intelligent applications that address real-world challenges. His talk introduced the audience to Spring AI’s capabilities, from simple “Hello World” examples to sophisticated use cases like question-and-answer systems over custom documents.
The Genesis of Spring AI
Mark began by sharing his journey into AI, sparked by the transformative impact of ChatGPT. Unlike traditional AI development, which often required extensive data cleaning and model training, pre-trained models like those from OpenAI offer accessible APIs and vast knowledge bases, enabling developers to focus on application engineering rather than data science. Mark highlighted how Spring AI emerged from his exploration of code generation, leveraging the structured nature of code within these models to create a framework tailored for Java developers. This framework abstracts the complexity of AI model interactions, making it easier to integrate AI into Spring-based applications.
Spring AI draws inspiration from Python’s AI ecosystem but adapts these concepts to Java’s idioms, emphasizing component abstractions and pluggability. Mark emphasized that this is not a direct port but a reimagination, aligning with the Spring ecosystem’s strengths in enterprise integration and batch processing. This approach positions Spring AI as a bridge between Java’s robust software engineering practices and the dynamic world of AI.
Core Components of AI Applications
A significant portion of Mark’s presentation focused on the architecture of AI applications, which extends beyond merely calling a model. He introduced a conceptual framework involving contextual data, AI frameworks, and models. Contextual data, akin to ETL (Extract, Transform, Load) processes, involves parsing and transforming data—such as PDFs—into embeddings stored in vector databases. These embeddings enable efficient similarity searches, crucial for use cases like question-and-answer systems.
Mark demonstrated a simple AI client in Spring AI, which abstracts interactions with various AI models, including OpenAI, Hugging Face, Amazon Bedrock, and Google Vertex. This portability allows developers to switch models without significant code changes. He also showcased the Spring CLI, a tool inspired by JavaScript’s Create React App, which simplifies project setup by generating starter code from existing repositories.
Prompt Engineering and Its Importance
Prompt engineering emerged as a critical theme in Mark’s talk. He explained that crafting effective prompts is essential for directing AI models to produce desired outputs, such as JSON-formatted responses or specific styles of answers. Spring AI’s PromptTemplate class facilitates this by allowing developers to create reusable, stateful templates with placeholders for dynamic content. Mark illustrated this with a demo where a prompt template generated a joke about a raccoon, highlighting the importance of roles (system and user) in defining the context and tone of AI responses.
He also touched on the concept of “dogfooding,” where AI models are used to refine prompts, creating a feedback loop that enhances their effectiveness. This iterative process, combined with evaluation techniques, ensures that applications deliver accurate and relevant responses, addressing challenges like model hallucinations—where AI generates plausible but incorrect information.
Retrieval Augmented Generation (RAG)
Mark introduced Retrieval Augmented Generation (RAG), a technique to overcome the limitations of AI models’ context windows, which restrict the amount of data they can process. RAG involves pre-processing data into smaller fragments, converting them into embeddings, and storing them in vector databases for similarity searches. This approach allows developers to provide only relevant data to the model, improving efficiency and accuracy.
In a demo, Mark showcased RAG with a bicycle shop dataset, where a question about city-commuting bikes retrieved relevant product descriptions from a vector store. This process mirrors traditional search engines but leverages AI to synthesize answers, demonstrating how Spring AI integrates with vector databases like Milvus and PostgreSQL to handle complex queries.
Real-World Applications and Future Directions
Mark highlighted practical applications of Spring AI, such as enabling question-and-answer systems for financial documents, medical records, or government programs like Medicaid. These use cases illustrate AI’s potential to make complex information more accessible, particularly for non-technical users. He also discussed the importance of evaluation in AI development, advocating for automated scoring mechanisms to assess response quality beyond simple test passing.
Looking forward, Mark outlined Spring AI’s roadmap, emphasizing robust core abstractions and support for a growing number of models and vector databases. He encouraged developers to explore the project’s GitHub repository and participate in its evolution, underscoring the rapid pace of AI advancements and the need for community involvement.
Links:
[DevoxxUK2024] Processing XML with Kafka Connect by Dale Lane
Dale Lane, a seasoned developer at IBM with a deep focus on event-driven architectures, delivered a compelling session at DevoxxUK2024, unveiling a powerful Kafka Connect plugin designed to streamline XML data processing. With extensive experience in Apache Kafka and Flink, Dale addressed the challenges of integrating XML data into Kafka pipelines, a task often fraught with complexity due to the format’s incompatibility with Kafka’s native data structures like Avro or JSON. His presentation offers practical solutions for developers seeking to bridge external systems with Kafka, transforming XML into more manageable formats or generating XML outputs for legacy systems. Through clear examples, Dale illustrates how this open-source plugin enhances flexibility and efficiency in Kafka Connect pipelines, empowering developers to handle diverse data integration scenarios with ease.
Understanding Kafka Connect Pipelines
Dale begins by demystifying Kafka Connect, a robust framework for moving data between Kafka and external systems. He outlines two primary pipeline types: source pipelines, which import data from external systems into Kafka, and sink pipelines, which export Kafka data to external destinations. A source pipeline typically involves a connector to fetch data, optional transformations to modify or filter it, and a converter to serialize the data into formats like Avro or JSON for Kafka topics. Conversely, a sink pipeline starts with a converter to deserialize Kafka data, followed by transformations and a connector to deliver it to an external system. This foundational explanation sets the stage for understanding where and how XML processing fits into these workflows, ensuring developers grasp the pipeline’s modular structure before diving into specific use cases.
Converting XML for Kafka Integration
A common challenge Dale addresses is integrating XML data from external systems, such as IBM MQ or XML-based web services, into Kafka’s ecosystem, which favors structured formats. He introduces the Kafka Connect plugin, available on GitHub under an Apache license, as a solution to parse XML into structured records early in the pipeline. For instance, using an IBM MQ source connector, the plugin can transform XML documents from a message queue into a generic structured format, allowing subsequent transformations and serialization into JSON or Avro. Dale demonstrates this with a weather API that returns XML strings, showing how the plugin converts these into structured objects for further processing, making them compatible with Kafka tools that struggle with raw XML. This approach significantly enhances the usability of external data within Kafka’s ecosystem.
Generating XML Outputs from Kafka
For scenarios where external systems require XML, Dale showcases the plugin’s ability to convert Kafka’s JSON or Avro messages into XML strings within a sink pipeline. He provides an example using a Kafka topic with JSON messages destined for an IBM MQ system, where the plugin, integrated as part of the sink connector, transforms structured data into XML before delivery. Another case involves an HTTP sink connector posting to an XML-based web service, such as an XML-RPC API. Here, the pipeline deserializes JSON, applies transformations to align with the API’s payload requirements, and uses the plugin to produce an XML string. This flexibility ensures seamless communication with legacy systems, bridging modern Kafka workflows with traditional XML-based infrastructure.
Enhancing Pipelines with Schema Support
Dale emphasizes the plugin’s schema handling capabilities, which add robustness to XML processing. In source pipelines, the plugin can reference an external XSD schema to validate and structure XML data, which is then paired with an Avro converter to submit schemas to a registry, ensuring compatibility with Kafka’s schema-driven ecosystem. In sink pipelines, enabling schema inclusion generates an XSD alongside the XML output, providing a clear description of the data’s structure. Dale illustrates this with a stock price connector, where enabling schema support produces XML events with accompanying XSDs, enhancing interoperability. This feature is particularly valuable for maintaining data integrity across systems, making the plugin a versatile tool for complex integration tasks.
Links:
[SpringIO2023] Beyond Routing: Spring Cloud Gateway with Style by Abel Salgado & Marta Medio
At Spring I/O 2023, Abel Salgado and Marta Medio, seasoned engineers from VMware, delivered an engaging session on elevating Spring Cloud Gateway beyond basic routing. Through practical, real-world examples and live demos, they showcased how to customize Spring Cloud Gateway with filters to address complex enterprise needs, such as security integrations and response modifications. Their talk demystified the gateway’s reactive stack, offering tips to avoid pitfalls and encouraging developers to harness its flexibility for performant, modular solutions.
Understanding Spring Cloud Gateway’s Power
Abel and Marta began by positioning Spring Cloud Gateway as a reactive, high-performance component that sits between clients and upstream services, enabling request and response manipulation. Unlike a one-to-one gateway tutorial, their session assumed basic familiarity, focusing on advanced customizations. They highlighted the gateway’s filter-based architecture, where filters operate in a chain, processing requests and responses in a defined order. This modularity allows developers to inject cross-cutting concerns like security or logging without altering upstream services. The duo emphasized the gateway’s potential to modernize legacy systems or split monoliths, making it a strategic tool for enterprise architectures.
Custom Filters for Security Integration
A key demo showcased how to implement OAuth security using Spring Cloud Gateway filters, integrating with Okta for token validation. Abel demonstrated two filters: one validating OAuth tokens using Spring Security’s resource server configuration, and another extracting claims (e.g., username) from the token to forward as HTTP headers to an upstream service unaware of OAuth. This approach isolates security logic in the gateway, sparing upstream services from modification. The demo, scripted with HTTPbin as the upstream service, illustrated a real-world scenario where a client authenticates with Okta, sends a token to the gateway, and receives a response with enriched headers. Abel stressed avoiding manual token validation, leveraging Spring Security’s reactive components to ensure performance and maintainability.
Dynamic Configuration and Response Modification
Marta explored the gateway’s configuration flexibility, demonstrating how to parametrize filters dynamically via YAML. A simple filter adding request headers was enhanced to accept multiple header configurations, reducing the need for multiple filter instances and improving performance. In a more complex example, Marta tackled modifying JSON responses from an upstream service, a common requirement when legacy APIs cannot be altered. Using a custom converter and the ModifyResponseBodyFilter, she transformed JSON fields based on YAML-defined key-value pairs, processing the response once to optimize performance. Marta cautioned about the performance risks of response modification, urging developers to carefully design configurations for scalability.
Best Practices and Community Insights
Abel and Marta concluded with practical advice for Spring Cloud Gateway adoption. They advocated for modular filter design to encapsulate features, enabling easy composition via YAML or actuator endpoints for runtime updates. They warned against reinventing solutions, citing cases where developers manually parsed JWTs instead of using Spring Security. The duo recommended reactive Spring libraries to avoid blocking issues and highlighted the gateway’s testing challenges, pointing to their GitHub repository for code examples. A nod to Spencer Gibb’s announcement about exploring MVC support for Spring Cloud Gateway underscored the project’s evolving potential. Their session inspired attendees to experiment with the gateway’s capabilities, leveraging its documentation and community resources.
Links:
[DevoxxBE2023] Securing the Supply Chain for Your Java Applications by Thomas Vitale
At Devoxx Belgium 2023, Thomas Vitale, a software engineer and architect at Systematic, delivered an authoritative session on securing the software supply chain for Java applications. As the author of Cloud Native Spring in Action and a passionate advocate for cloud-native technologies, Thomas provided a comprehensive exploration of securing every stage of the software lifecycle, from source code to deployment. Drawing on the SLSA framework and CNCF research, he demonstrated practical techniques for ensuring integrity, authenticity, and resilience using open-source tools like Gradle, Sigstore, and Kyverno. Through a blend of theoretical insights and live demonstrations, Thomas illuminated the critical importance of supply chain security in today’s threat landscape.
Safeguarding Source Code with Git Signatures
Thomas began by defining the software supply chain as the end-to-end process of delivering software, encompassing code, dependencies, tools, practices, and people. He emphasized the risks at each stage, starting with source code. Using Git as an example, Thomas highlighted its audit trail capabilities but cautioned that commit authorship can be manipulated. In a live demo, he showed how he could impersonate a colleague by altering Git’s username and email, underscoring the need for signed commits. By enforcing signed commits with GPG or SSH keys—or preferably a keyless approach via GitHub’s single sign-on—developers can ensure commit authenticity, establishing a verifiable provenance trail critical for supply chain security.
Managing Dependencies with Software Bills of Materials (SBOMs)
Moving to dependencies, Thomas stressed the importance of knowing exactly what libraries are included in a project, especially given vulnerabilities like Log4j. He introduced Software Bills of Materials (SBOMs) as a standardized inventory of software components, akin to a list of ingredients. Using the CycloneDX plugin for Gradle, Thomas demonstrated generating an SBOM during the build process, which provides precise dependency details, including versions, licenses, and hashes for integrity verification. This approach, integrated into Maven or Gradle, ensures accuracy over post-build scanning tools like Snyk, enabling developers to identify vulnerabilities, check license compliance, and verify component integrity before production.
Thomas further showcased Dependency-Track, an OWASP project, to analyze SBOMs and flag vulnerabilities, such as a critical issue in SnakeYAML. He introduced the Vulnerability Exploitability Exchange (VEX) standard, which complements SBOMs by documenting whether vulnerabilities affect an application. In his demo, Thomas marked a SnakeYAML vulnerability as a false positive due to Spring Boot’s safe deserialization, demonstrating how VEX communicates security decisions to stakeholders, reducing unnecessary alerts and ensuring compliance with emerging regulations.
Building Secure Artifacts with Reproducible Builds
The build phase, Thomas explained, is another critical juncture for security. Using Spring Boot as an example, he outlined three packaging methods: JAR files, native executables, and container images. He critiqued Dockerfiles for introducing non-determinism and maintenance overhead, advocating for Cloud Native Buildpacks as a reproducible, secure alternative. In a demo, Thomas built a container image with Buildpacks, highlighting its fixed creation timestamp (January 1, 1980) to ensure identical outputs for unchanged inputs, enhancing security by eliminating variability. This reproducibility, coupled with SBOM generation during the build, ensures artifacts are both secure and traceable.
Signing and Verifying Artifacts with SLSA
To ensure artifact integrity, Thomas introduced the SLSA framework, which provides guidelines for securing software artifacts across the supply chain. He demonstrated signing container images with Sigstore’s Cosign tool, using a keyless approach to avoid managing private keys. This process, integrated into a GitHub Actions pipeline, ensures that artifacts are authentically linked to their creator. Thomas further showcased SLSA’s provenance generation, which documents the artifact’s origin, including the Git commit hash and build steps. By achieving SLSA Level 3, his pipeline provided non-falsifiable provenance, ensuring traceability from source code to deployment.
Securing Deployments with Policy Enforcement
The final stage, deployment, requires validating artifacts to ensure they meet security standards. Thomas demonstrated using Cosign and the SLSA Verifier to validate signatures and provenance, ensuring only trusted artifacts are deployed. On Kubernetes, he introduced Kyverno, a policy engine that enforces signature and provenance checks, automatically rejecting non-compliant deployments. This approach ensures that production environments remain secure, aligning with the principle of validating metadata to prevent unauthorized or tampered artifacts from running.
Conclusion: A Holistic Approach to Supply Chain Security
Thomas’s session at Devoxx Belgium 2023 provided a robust framework for securing Java application supply chains. By addressing source code integrity, dependency management, build reproducibility, artifact signing, and deployment validation, he offered a comprehensive strategy to mitigate risks. His practical demonstrations, grounded in open-source tools and standards like SLSA and VEX, empowered developers to adopt these practices without overwhelming complexity. Thomas’s emphasis on asking “why” at each step encouraged attendees to tailor security measures to their context, ensuring both compliance and resilience in an increasingly regulated landscape.
Links:
[KotlinConf2023] Java and Kotlin: A Mutual Evolution
At KotlinConf2024, John Pampuch, Google’s production languages lead, delivered a history lesson on Java and Kotlin’s intertwined journeys. Battling jet lag with humor, John traced nearly three decades of Java and twelve years of Kotlin, emphasizing their complementary strengths. From Java’s robust ecosystem to Kotlin’s pragmatic innovation, the languages have shaped each other, accelerating progress. John’s talk, rooted in his experience since Java’s 1996 debut, explored design goals, feature cross-pollination, and future implications, urging developers to leverage Kotlin’s developer-friendly features while appreciating Java’s stability.
Design Philosophies: Pragmatism Meets Robustness
John opened by contrasting the languages’ origins. Java, launched in 1995, aimed for simplicity, security, and portability, aligning tightly with the JVM and JDK. Its ecosystem, bolstered by libraries and tooling, set a standard for enterprise development. Kotlin, announced in 2011 by JetBrains, prioritized pragmatism: concise syntax, interoperability with Java, and multiplatform flexibility. Unlike Java’s JVM dependency, Kotlin targets iOS, web, and beyond, enabling faster feature rollouts. John noted Kotlin’s design avoids Java’s rigidity, embracing object-oriented principles with practical tweaks like semicolon-free lines. Yet Java’s self-consistency, seen in its holistic lambda integration, complements Kotlin’s adaptability, creating a synergy where both thrive.
Feature Evolution: From Lambdas to Coroutines
The talk highlighted key milestones. Java’s 2014 release of JDK 8 introduced lambdas, default methods, and type inference, transforming APIs to support functional programming. Kotlin, with 1.0 in 2016, brought smart casts, string templates, and named arguments, prioritizing developer ease. By 2018, Kotlin’s coroutines revolutionized JVM asynchronous programming, offering a simpler mental model than Java’s threads. John praised coroutines as a potential game-changer, though Java’s 2023 virtual threads and structured concurrency aim to close the gap. Kotlin’s multiplatform support, cemented by Google’s 2017 Android endorsement, outpaces Java’s JVM-centric approach, but Java’s predictable six-month release cycle since 2017 ensures steady progress. These advancements reflect a race where each language pushes the other forward.
Mutual Influences: Sealed Classes and Beyond
John emphasized cross-pollination. Java’s 2021 records, inspired by frameworks like Lombok, mirror Kotlin’s data classes, though Kotlin’s named parameters reduce boilerplate further. Sealed classes, introduced in Java 17 and Kotlin 1.5 around 2021, emerged concurrently, suggesting shared inspiration. Kotlin’s string templates, a staple since its early days, influenced Java’s 2024 preview of flexible string templates, which John hopes Kotlin might adopt for localization. Java’s exploration of nullability annotations, potentially aligning with Kotlin’s robust null safety, shows ongoing convergence. John speculated that community demand could push Java toward features like named arguments, though JVM changes remain a hurdle. This mutual learning, fueled by competition with languages like Go and Rust, drives excitement and innovation.
Looking Ahead: Pragmatism and Compatibility
John concluded with a call to action: embrace Kotlin’s compact, readable features while valuing Java’s compile-time speed and ecosystem. Kotlin’s faster feature delivery and multiplatform prowess contrast with Java’s backwards compatibility and predictability. Yet both share a commitment to pragmatic evolution, avoiding breaks in millions of applications. Questions from the audience probed Java’s nullability and virtual threads, with John optimistic about eventual alignment but cautious about timelines. His talk underscored that Java and Kotlin’s competition isn’t zero-sum—it’s a catalyst for better tools, ideas, and developer experiences, ensuring both languages remain vital.
Links:
Hashtags: #Java #Kotlin
[DevoxxBE2023] REST Next Level: Crafting Domain-Driven Web APIs by Julien Topçu
At Devoxx Belgium 2023, Julien Topçu, a technical coach at Shadow, delivered a compelling session on elevating REST APIs by embedding domain-driven design principles. With a rich background in crafting software using Domain-Driven Design (DDD), Extreme Programming, and Kanban, Julien illuminated the pitfalls of traditional REST implementations and proposed a transformative approach to encapsulate business intent within APIs. His talk, centered around a fictional space travel booking system, demonstrated how to align APIs with user actions, preserve business workflows, and enhance consumer experience through hypermedia controls. Through a blend of theoretical insights and practical demonstrations, Julien showcased a methodology to create APIs that are not only functional but also semantically rich and workflow-driven.
The Pitfalls of Traditional REST APIs
Julien began by highlighting a pervasive issue in software architecture: the loss of business intent when translating domain logic into REST APIs. Typically, business logic resides in the backend to avoid duplication across consumers like web or mobile applications. However, REST’s uniform interface, with its limited vocabulary of CRUD operations (Create, Read, Update, Delete), often distorts this logic. For instance, in a train reservation system, a user’s intent to “search for trains” is reduced to “create a search resource,” stripping away domain-specific semantics like destinations or schedules. This mismatch, Julien argued, stems from REST’s standardized approach, formalized by Roy Fielding in his PhD thesis, which prioritizes simplicity over application-specific needs. As a result, APIs lose expressiveness, forcing consumers to reconstruct business workflows, leading to what Julien termed “accidental complexity of adaptation.”
To illustrate, Julien presented a scenario where a user performs a search for space trains from Earth to the Moon. The traditional REST API translates this into a POST request to create a search resource, devoid of domain context. This not only obscures the user’s intent but also couples consumers to the backend’s implementation, making changes—like switching from “bound” to “journey index” for multi-destination trips—disruptive. Julien’s live demo underscored this fragility: altering a request parameter broke the API, highlighting the risks of tight coupling between consumers and backend models.
Encapsulating Business Intent with Semantic Endpoints
To address these shortcomings, Julien proposed aligning REST endpoints with user actions rather than backend models. Instead of exposing implementation details, such as updating a sub-resource like “selection” within a search, APIs should reflect behaviors like “select a space train with a fare.” This approach involves using classifiers in URLs, such as POST /searches/{id}/spacetrains/{number}/fares/{code}/select, which clearly convey the intent of selecting a fare for a specific train. Julien emphasized that this does not violate REST principles, debunking the myth that verbs in URLs are forbidden. As long as verbs align with HTTP methods (e.g., POST for creating a resource), they enhance semantic clarity without breaking the uniform interface.
This shift decouples consumers from the backend’s internal structure. For example, changing the backend’s data model (e.g., using booleans instead of a selection object) no longer impacts consumers, as the API exposes behaviors rather than state. Julien’s demo further showcased this by demonstrating how a frontend could adapt to backend changes (e.g., from “bound” to “journey index”) without modification, thanks to semantic endpoints. This approach not only preserves business intent but also simplifies consumer logic, reducing the cognitive load of interpreting CRUD-based APIs.
Encapsulating Workflows with Hypermedia Controls
A critical challenge Julien addressed is the lack of workflow definition in traditional REST APIs. Typically, consumers must hardcode business workflows, such as the sequence of selecting outbound and inbound trains before booking. This leads to duplicated logic and potential errors, like displaying a booking button prematurely. Julien introduced hypermedia controls, specifically HATEOAS (Hypermedia As The Engine Of Application State), as a solution. By embedding links in API responses, the backend can guide consumers through the workflow dynamically.
In his demo, Julien showed how a search response includes links like select-outbound and all-inbounds, which guide the consumer to the next valid actions. For instance, after selecting an outbound train, the response provides a link to select an inbound train, ensuring only compatible options are available. This encapsulation of workflow logic in the backend eliminates the need for consumers to understand the sequence of actions, reducing errors and enhancing maintainability. Julien highlighted that this approach, part of the Richardson Maturity Model’s Level 3, makes APIs discoverable and resilient to backend changes, as consumers rely on links rather than hardcoded URLs.
Practical Implementation and Limitations
Julien’s live coding demo brought these concepts to life, showcasing a Spring Boot backend in Kotlin that dynamically generates links based on the application state. For example, the create-booking link only appears when the selection is complete, ensuring consumers cannot book prematurely. This dynamic guidance, facilitated by Spring HATEOAS, allows the frontend to display UI elements like the booking button based solely on available links, streamlining development and enhancing user experience.
However, Julien acknowledged limitations. For complex forms requiring extensive user input, the hypermedia approach may need supplementation with predefined payloads, as consumers must know what data to send. Additionally, long URLs, while not a practical issue in Julien’s experience at Expedia, could pose challenges in some contexts. Despite these constraints, the approach excels in domains with well-defined workflows, offering a robust framework for building expressive, maintainable APIs.
Conclusion: A New Paradigm for REST APIs
Julien’s session at Devoxx Belgium 2023 offered a transformative vision for REST APIs, emphasizing the power of domain-driven design and hypermedia controls. By aligning endpoints with user actions, encapsulating behaviors, and guiding workflows through links, developers can create APIs that are both semantically rich and resilient to change. This approach not only enhances consumer experience but also aligns with the principles of DDD, ensuring that business intent remains at the forefront of API design. Julien’s practical insights and engaging demo left attendees inspired to rethink their API strategies, fostering a deeper appreciation for REST’s potential when infused with domain-driven principles.
Links:
[DevoxxBE2023] The Panama Dojo: Black Belt Programming with Java 21 and the FFM API by Per Minborg
In an engaging session at Devoxx Belgium 2023, Per Minborg, a Java Core Library team member at Oracle and an OpenJDK contributor, guided attendees through the intricacies of the Foreign Function and Memory (FFM) API, a pivotal component of Project Panama. With a blend of theoretical insights and live coding, Per demonstrated how this API, in its third preview in Java 21, enables seamless interaction with native memory and functions using pure Java code. His talk, dubbed the “Panama Dojo,” showcased the API’s potential to enhance performance and safety, culminating in a hands-on demo of a lightweight microservice framework built with memory segments, arenas, and memory layouts.
Unveiling the FFM API’s Capabilities
Per introduced the FFM API as a solution to the limitations of Java Native Interface (JNI) and direct buffers. Unlike JNI, which requires cumbersome C stubs and inefficient data passing, the FFM API allows direct native memory access and function calls. Per illustrated this with a Point struct example, where a memory segment models a contiguous memory region with 64-bit addressing, supporting both heap and native segments. This eliminates the 2GB limit of direct buffers, offering greater flexibility and efficiency.
The API introduces memory segments with constraints like size, lifetime, and thread confinement, preventing out-of-bounds access and use-after-free errors. Per highlighted the importance of deterministic deallocation, contrasting Java’s automatic memory management with C’s manual approach. The FFM API’s arenas, such as confined and shared arenas, manage segment lifecycles, ensuring resources are freed explicitly, as demonstrated in a try-with-resources block that deterministically deallocates a segment.
Structuring Memory with Layouts and Arenas
Memory layouts, a key FFM API feature, provide a declarative way to define memory structures, reducing manual offset computations. Per showed how a Point layout with x and y doubles uses var handles to access fields safely, leveraging JIT optimizations for atomic operations. This approach minimizes bugs in complex structs, as var handles inherently account for offsets, unlike manual calculations.
Arenas further enhance safety by grouping segments with shared lifetimes. Per demonstrated a confined arena, restricting access to a single thread, and a shared arena, allowing multi-threaded access with thread-local handshakes for safe closure. These constructs bridge the gap between C’s flexibility and Rust’s safety, offering a balanced model for Java developers. In his live demo, Per used an arena to allocate a MarketInfo segment, showcasing deterministic deallocation and thread safety.
Building a Persistent Queue with Memory Mapping
The heart of Per’s session was a live coding demo constructing a persistent queue using memory mapping and atomic operations. He defined a MarketInfo record for stock exchange data, including timestamp, symbol, and price fields. Using a record mapper, Per serialized and deserialized records to and from memory segments, demonstrating immutability and thread safety. The mapper, a potential future JDK feature, simplifies data transfer between Java objects and native memory.
Per then implemented a memory-mapped queue, where a file-backed segment stores headers and payloads. Headers use atomic operations to manage mutual exclusion across threads and JVMs, ensuring safe concurrent access. In the demo, a producer appended MarketInfo records to the queue, while two consumers read them asynchronously, showcasing low-latency, high-performance data sharing. Per’s use of sparse files allowed a 1MB queue to scale virtually, highlighting the API’s efficiency.
Crafting a Microservice Framework
The session culminated in assembling these components into a microservice framework. Per’s queue, inspired by Chronicle Queue, supports persistent, high-performance data exchange across JVMs. The framework leverages memory mapping for durability, atomic operations for concurrency, and record mappers for clean data modeling. Per demonstrated its practical application by persisting a queue to a file and reading it in a separate JVM, underscoring its robustness for distributed systems.
He emphasized the reusability of these patterns across domains like machine learning and graphics processing, where native libraries are prevalent. Tools like jextract, briefly mentioned, further unlock native libraries like TensorFlow, enabling Java developers to integrate them effortlessly. Per’s framework, though minimal, illustrates how the FFM API can transform Java’s interaction with native code, offering a safer, faster alternative to JNI.
Performance and Safety in Harmony
Throughout, Per stressed the FFM API’s dual focus on performance and safety. Native function calls, faster than JNI, and memory segments with strict constraints outperform direct buffers while preventing common errors. The API’s integration with existing JDK features, like var handles, ensures compatibility and optimization. Per’s live coding, despite its complexity, flowed seamlessly, reinforcing the API’s practicality for real-world applications.
Conclusion: Embracing the Panama Dojo
Per’s session was a masterclass in leveraging the FFM API to push Java’s boundaries. By combining memory segments, layouts, arenas, and atomic operations, he crafted a framework that exemplifies the API’s potential. His call to action—experiment with the FFM API in Java 21—invites developers to explore this transformative tool, promising enhanced performance and safety for native interactions. The Panama Dojo left attendees inspired to break new ground in Java development.
Links:
[DevoxxBE2023] Java Language Update by Brian Goetz
At Devoxx Belgium 2023, Brian Goetz, Oracle’s Java Language Architect, delivered an insightful session on the evolution of Java, weaving together a narrative of recent advancements, current features in preview, and a vision for the language’s future. With his deep expertise, Brian illuminated how Java balances innovation with compatibility, ensuring it remains a cornerstone of modern software development. His talk explored the introduction of records, sealed classes, pattern matching, and emerging features like string templates and simplified program structures, all designed to enhance Java’s expressiveness and accessibility. Through a blend of technical depth and practical examples, Brian showcased Java’s commitment to readable, maintainable code while addressing contemporary programming challenges.
Reflecting on Java’s Recent Evolution
Brian began by recapping Java’s significant strides since his last Devoxx appearance, highlighting features like records, sealed classes, and pattern matching. Records, introduced as nominal tuples, provide a concise way to model data with named components, enhancing readability over structural tuples. For instance, a Point record with x and y coordinates is more intuitive than an anonymous tuple of integers. By deriving constructors, accessors, and equality methods from a state declaration, records eliminate boilerplate while making a clear semantic statement about data immutability. Brian emphasized that this semantic focus, rather than mere syntax reduction, distinguishes Java’s approach from alternatives like Lombok.
Sealed classes, another recent addition, allow developers to restrict class hierarchies, specifying permitted subtypes explicitly. This enables libraries to expose abstract types while controlling implementations, as seen in the JDK’s use of method handles. Sealed classes also enhance exhaustiveness checking in switch statements, reducing runtime errors by ensuring all cases are covered. Brian illustrated this with a Shape hierarchy, where a sealed interface permits only Circle and Rectangle, allowing the compiler to verify switch completeness without a default clause.
Advancing Data Modeling with Pattern Matching
Pattern matching, a cornerstone of Java’s recent enhancements, fuses type testing, casting, and binding into a single operation, reducing errors from manual casts. Brian demonstrated how type patterns, like if (obj instanceof String s), streamline code by eliminating redundant casts. Record patterns extend this by deconstructing objects into components, enabling recursive matching for nested structures. For example, a Circle record with a Point center can be matched to extract x and y coordinates in one expression, enhancing both concision and safety.
The revamped switch construct, now an expression supporting patterns and guards, further leverages these capabilities. Brian highlighted its exhaustiveness checking, which uses sealing information to ensure all cases are handled, as in a Color interface sealed to Red, Yellow, and Green. This eliminates the need for default clauses, catching errors at compile time if the hierarchy evolves. By combining records, sealed classes, and pattern matching, Java now supports algebraic data types, offering a powerful framework for modeling complex domains like expressions, where a sealed Expression type can be traversed elegantly with pattern-based recursion.
Introducing String Templates for Safe Aggregation
Looking to the future, Brian introduced string templates, a preview feature addressing the perils of string interpolation. Unlike traditional concatenation or formatting methods, string templates use a template processor to safely combine text fragments and expressions. A syntax like STR.FMT."Hello, \{name\}!" invokes a processor to validate inputs, preventing issues like SQL injection. Brian envisioned a SQL template processor that balances quotes and produces a result set directly, bypassing string intermediaries for efficiency and security. Similarly, a JSON processor could streamline API development by constructing objects from raw fragments, enhancing performance.
This approach reframes interpolation as a broader aggregation problem, allowing developers to define custom processors for domain-specific needs. Brian’s emphasis on safety and flexibility underscores Java’s commitment to robust APIs, drawing inspiration from JavaScript’s tagged functions and Scala’s string interpolators, but tailored to Java’s ecosystem.
Simplifying Java’s On-Ramp and Beyond
To make Java for new developers, Brian discussed preview features like unnamed classes and patterns, which reduce boilerplate for simple programs. A minimal program might omit public static void main, allowing beginners to focus on core logic rather than complex object-oriented constructs. This aligns Java with languages like Python, where incremental learning is prioritized, easing the educational burden on instructors and students alike.
Future enhancements include reconstruction patterns for immutable objects, enabling concise updates like p.with(x: 0) to derive new records from existing ones. Brian also proposed deconstructor patterns for regular classes, mirroring constructors to enable pattern decomposition, enhancing API symmetry. These features aim to make aggregation and decomposition reversible, reducing error-prone asymmetries in object manipulation. For instance, a Person class could declare a deconstructor to extract first and last names, mirroring its constructor, streamlining data handling across Java’s object model.
Conclusion: Java’s Balanced Path Forward
Brian’s session underscored Java’s deliberate evolution, balancing innovation with compatibility. By prioritizing readable, maintainable code, Java addresses modern challenges like loosely coupled services and untyped data, positioning itself as a versatile language for data modeling. Features like string templates and simplified program structures promise greater accessibility, while pattern matching and deconstruction patterns enhance expressiveness. As Java continues to refine its features, it remains a testament to thoughtful design, ensuring developers can build robust, future-ready applications.
Links:
[AWS Summit Berlin 2023] Go-to-Market with Your Startup: Tips and Best Practices from VC Investors
At AWS Summit Berlin 2023, David Roldán, Head of Startup Business Development for EMEA at AWS, led a 48-minute panel, available on YouTube, featuring VC investors and operators: Constantine, CTO and co-founder of PlanRadar, Jasper, partner at Cherry Ventures, and Gloria, founder of Beyond Capital. This post, targeting startup founders, explores go-to-market (GTM) strategies for B2B SaaS, emphasizing product-segment fit, iterative processes, and avoiding premature scaling in a competitive landscape with over 100,000 independent software vendors.
Defining Product-Segment Fit
Jasper introduced the concept of product-segment fit, arguing it’s more precise than product-market fit for early-stage startups. He emphasized that founders should target a specific customer segment where the product resonates strongly, rather than chasing universal appeal. For example, PlanRadar, serving the construction industry, found success by focusing on old-fashioned outbound sales to reach decision-makers in a niche vertical. Gloria reinforced this, noting that chasing a single “killer feature” often distracts from solving core use cases. Instead, founders should iterate based on customer feedback, ensuring the product delivers immediate value to a well-defined audience, avoiding dilution of focus across disparate segments.
Iterative GTM Strategies
Constantine shared PlanRadar’s journey, highlighting the iterative nature of GTM. With a five-founder team spanning commercial, industry, and tech expertise, PlanRadar prioritized early customer feedback over polished features. He advised launching minimum viable products to test assumptions, even if imperfect, to refine offerings rapidly. Gloria added that data infrastructure, like a well-structured CRM, is critical before Series A to track sales cycles and conversion stages. However, Jasper cautioned against over-rationalizing early GTM with tools like Salesforce, which can burden seed-stage startups. Instead, founders should stay hands-on, engaging directly with customers to build velocity in the sales pipeline.
Avoiding Premature Scaling
Gloria and Constantine stressed the dangers of premature scaling, particularly in hiring. Gloria advised against hiring product managers too early, recommending product engineers who can own the roadmap alongside founders until post-Series A. Constantine echoed this, noting PlanRadar delayed building a product management team until after Series A due to workload and complexity, hiring an ex-founder after a year-long search. Jasper highlighted that premature hires, like sales managers craving predictability, can push startups to scale in the wrong segment, leading to misaligned products. The panel agreed that founders must retain product vision, avoiding delegation to non-founders who lack the same long-term perspective.
Customer Success and Retention
Retention emerged as a key GTM metric, but its priority depends on stage. Gloria argued that early churn is acceptable to refine product-segment fit, but post-product-market fit, net retention becomes critical, reflecting customer love through renewals and upsells. Constantine detailed PlanRadar’s post-Series A customer success team, which segments customers (gold, silver, bronze) using usage data to allocate scarce resources effectively. He noted charging for onboarding, common in Europe, boosts engagement by signaling value. Gloria emphasized three pillars: activation (fast onboarding), engagement (tracking feature usage), and renewals (modularizing products for cross-selling), ensuring startups maximize lifetime value as they scale.