Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

New HTTP clients, a Java generator, and more in Fabric8 6.0.0

July 15, 2022
Steven Hawkins Andrea Peruffo
Related topics:
JavaKubernetes
Related products:
Red Hat build of OpenJDKRed Hat build of QuarkusRed Hat JBoss Enterprise Application Platform

Share:

    The Fabric8 Kubernetes client has been simplifying Java developers' use of Kubernetes for several years. The 6.0.0 release represents a major body of work spanning about five months of effort in both the core of the project and in related utilities.

    This article takes a look at new features and other important changes in the Fabric8 Kubernetes client, including:

    • New HTTP clients
    • Java generator
    • Resource API
    • API refinements
    • Kubernetes testing improvements

    How to get the new Fabric8 Java client

    You can find the most current Fabric8 Java client release on Maven Central. To start using the new client, add it as a dependency in your Maven pom.xml or Gradle build file. For Kubernetes, the dependency is:

    <dependency>
      <groupId>io.fabric8</groupId>
      <artifactId>kubernetes-client</artifactId>
      <version>6.0.0</version>
    </dependency>
    

    Or for Red Hat OpenShift:

    <dependency>
      <groupId>io.fabric8</groupId>
      <artifactId>openshift-client</artifactId>
      <version>6.0.0</version>
    </dependency>
    

    The sections below on the new HTTP clients API refinements will help you understand the new choices you have in your Fabric8 client dependencies.

    And for your future Fabric8 Kubernetes client needs, please use the snapshot releases being published to Maven Central.

    New features

    The feature work of the Fabric8 client has been driven by a diverse set of needs with an eye towards compatibility and continuity for existing users. So while the changelog and migration guide may be lengthy, we expect that your upgrade process will be mostly seamless.

    New HTTP clients

    With some refinements to the HTTP client API introduced in 5.x, we were able to create a JDK and an Eclipse Jetty client implementation. A Vert.x client is still in the works.

    This means you can choose the client that is best suited to your needs—which could be one that is already being used in your project. You won't be locked into additional OkHttp dependencies unless you want to be.

    Since the abstraction layer and alternative client implementations are new, please let us know if you encounter any issues with them. You should also check the repo for known issues with the respective implementation—the JDK readme, for example.

    The FAQ covers how to configure your project for a given HTTP client, along with several other topics. In short, you should exclude the kubernetes-httpclient-okhttp dependency and add a runtime dependency to the desired HTTP client: kubernetes-httpclient-jetty or kubernetes-httpclient-jdk.

    If you need to customize the configuration of the client, you should add a compile time reference to the respective HTTP client—kubernetes-httpclient-xxx—and extend its HttpClient.Factory: JettyHttpClientFactory, JdkHttpClientFactory, and OkHttpClientFactory.

    Java generator

    Kubernetes is still a world dominated by Go tools and operators. When using the kubernetes-client, you often have to deal with externally defined (and generated) Custom Resource Definitions (CRDs). So far, the extensions available for Fabric8 have partially closed the gap by offering typed Java representations for some common use cases. In the 6.x release, we are introducing a full blown Java generator capable of automatically extracting fully typed Java representations from arbitrary YAML/JSON CRDs. You can check some examples of the generated code here.

    The tool can generate Java classes annotated with lombok and sundrio annotations in order to provide a seamless API and user experience when using those.

    Whether you want to easily and quickly interact with Java code with an external CRD, or you want to go down the path of full contract first development in your Operator, the Java generator is the instrument you are looking for.

    Eager to start? You can find detailed instructions on how to use it in the official documentation.

    Resource API

    Most operations are performed on a resource. The Fabric8 5.x APIs could make dealing with existing KubernetesResource objects a little cumbersome when it came to obtaining the resource. It was quite common to do something like this:

    // obtain an existing configMap somehow
    ConfigMap configMap = ...
    ...
    Resource<ConfigMap> resource = client.configMaps().inNamespace(configMap.getMetadata().getNamespace()).withName(configMap.getMetadata().getName());
    resource.delete(); // or some other operation
    

    In 6.0, several issues have been addressed, including #3407 and #3973, that make it possible to obtain the Resource directly:

    Resource<ConfigMap> resource = client.resource(configMap);
    // or used fluently
    client.resource(configMap).delete();
    

    There are other places to directly get resources. For instance, all of the following return a Stream>:

    client.configMaps().resources(); 
    client.configMaps().withLabel("x").resources();
    client.resourceList(...).resources();
    

    Using any of these, you can implement composite operations easily with lambdas:

    client.secrets().resources().forEach(Resource::delete);
    

    Related to these changes are the cleanup and deprecation of many common operations. For example, imagine a scenario where you used both withName() and a resource to perform an operation:

    client.configMaps().withName("x").replace(configMap);
    

    This was potentially confusing in that there was an extra check to make sure that the name specified in withName() matched the name of the KubernetesResource passed into replace(). With 6.0, you should instead perform the operations on the resource:

    // if you need a specific resource type
    client.configMaps().resource(configMap).replace();
    
    // or if it can be a general Resource
    client.resource(configMap).replace();
    

    API refinements

    The 6.0 update has gone went beyond simply adding a few new things into the domain-specific language (DSL). The DSL has now been split from the implementation and has been cleaned out of anything that seemed unnecessary.

    The 5.x client and prior versions had the primary API and implementation as a single kubernetes-client module/jar. While convenient, it did not offer a clear separation of the API from internal classes, and exposed the consuming applications compile time classpath to additional dependencies (such as OkHttp). A refactoring was undertaken to split the client into a separate API and implementation module. You may still continue to use just a reference to the kubernetes-client if you wish, but you now also have the option of having a compile dependency on kubernetes-client-api with a runtime dependency on kubernetes-client.

    This split also required us to make direct use of the default clients; DefaultKubernetesClient and DefaultOpenShiftClient have been deprecated. You should transition to using the KubernetesClientBuilder instead, which you will be required to use if you have just the API module as a compile time dependency.

    This refactoring allowed us to clean up some of the details of how the client extensions are implemented. They now only have a compile dependency on the kubernetes-client-api, so you may notice a few changes if you use or further extend an extension such as Camel K, Istio, cert-manager, etc.

    Finally, we took this opportunity to remove or collapse a lot of the interfaces that were used to make up the DSL. Most users, who are using fluent style calls, won't notice these changes as the operations are still there. However, if you created an intermediate variable at some point in the method chain, that particular class may no longer exist; for example, EditReplacePatchDeleteble is no more. In that case, you'll have to update the type or use var instead.

    Kubernetes testing improvements

    The integration testing utilities used by the Fabric8 project were refined and exposed for general use as a JUnit 5 extension in a new kubernetes-junit-jupiter artifact. The new module offers a highly declarative set of annotations that you can use to simplify your project's test setup and execution against an actual Kubernetes cluster.

    As described in issued #4054, this module allows you to configure your tests like so:

    @KubernetesTest
    @LoadKubernetesManifests("/test-data.yml")
    @RequireK8sSupport(io.fabric8.knative.serving.v1.Service.class) // Optionally require support for a resource  (test env should be reliable)
    @RequireK8sVersionAtLeast(majorVersion = 1, minorVersion = 16) // Optionally require a specific K8s version
    class MyTest {
      KubernetesClient client;
      // …
    }
    

    The extension takes care of creating a temporary namespace and injecting a KubernetesClient instance preconfigured to use that namespace. In addition, the new extension provides an annotation to load and delete Kubernetes manifests before and after the test suite execution, along with two annotations to restrict the test execution to specific cluster versions, or support for specific Kubernetes resources.

    Unit testing using the Kubernetes Mock server was also improved:

    • You no longer need extension-specific modules such as tekton-tests. Instead, you may directly reference the client type you need as a member variable. The appropriate instance will be initialized:
      @EnableKubernetesMockClient
      Class MyTest {
      TektonClient client;
      // …
      }
      
    • Issue #3966: The KubernetesMockServer has new methods— reset() and unsupported()— to reset its state and control what APIs are unsupported. The reset() method is especially useful in crud mode to quickly clean out the mock server resource state in between tests.
    • Issue #3758: VersionInfo in KubernetesMockServer can be overridden.

    Other improvements

    • Issue #3334: Added basic support for server-side apply: patch(PatchContext.of(PatchType.SERVER_SIDE_APPLY), service).

    • Issue #3625: Added default maps in generated models, mostly to prevent the need for null checks on things like annotations and labels.

    • Informer improvements:

      • Issue #3968: SharedIndexInformer.initialState can be used to set the store state before the informer starts.
      • SharedIndexInformer allows for the addition and removal of indexes even after starting, and you can remove the default namespace index if you wish.
      • Store.getKey() can be used rather than directly referencing static cache functions.
      • Issues #3472 and #3587: Customization has been opened up for the Informer store/cache key function and the way in which state is stored. See BasicItemStore, ReducedStateItemStore, and the SharedIndexInformer.itemStore() function.
    • Issue #3922: Added Client.supports() and Client.hasApiGroup() methods for API server metadata introspection.

    Deprecations and other important changes

    Since this is a major release there was quite a bit of legacy removed or deprecated, and there are various breaking changes. This section will cover some of the highlights, but please see the migration guide for a full list.

    • To match the behavior of kubectl, the client will now consider any call to inNamespace as the namespace to use regardless of what is on a passed in item. Only if the client is left at the default namespace or a call has been made to inAnyNamespace will the item namespace be used. This applies to all calls to inNamespace at the client, operation, or resource level, and for all operations (load, create, delete, withItem, etc.).

    • The backwards compatibility interceptor is now disabled by default.

    • The apiVersion on a resource being deserialized is now required.

    • Deleting a collection is now implemented using a single delete call, rather than for each item. When the collection is namespaced and inAnyNamespace is used, a call will be made to first determine the affected namespaces, and then a collection delete issued against each namespace. The result of the delete calls will be a list of StatusDetails rather than a boolean value. A best effort is made to process the response from the server to populate the items that are deleted. This information is generally useful if you wish to implement some kind of blocking delete behavior—that is, if you want to ensure the returned resources (based upon a matching UID) have been deleted.

    • delete(List<T>) and delete(T[]) returning boolean have been deprecated. They will always return TRUE, and 404s on individual items will simply be ignored.

    • Client.isAdaptable() and Client.adapt() will check first if the existing client is an instance of the desired type. Client.adapt() will no longer perform the isAdaptable() check—that is, you may freely adapt from one client to another as long as the extension exists. If you need to make a specific check of support, please use the Client.supports() method.

    • Evictable.evict() will throw an exception rather than returning FALSE if the pod is not found. This ensures that FALSE strictly means that the eviction failed.

    • The usage of piped streams is no longer supported—they make assumptions about reading and writing threads, which the client no longer honors. They should not be passed into the methods accepting InputStreams and OutputStreams.
      ContainerResource.writingInput(PipedOutputStream in) and readingXXX(PipedInputStream out) have been removed—use the redirecting methods instead.

    • TtyExecErrorChannelable methods have been deprecated in favor of ExecWatch.exitCode() and ExecListener.onExit().
      ContainerResource.readingInput(InputStream in) has been deprecated—use redirectingInput() instead.

    Learn more about Fabric8

    Fabric8's development team consists mostly of Java developers, so a Java developer's perspective heavily influences this client. If you want to work with us, please don't hesitate to join our community. There are a few ways to get involved with the development of the Fabric8 Kubernetes Java client:

    • Create GitHub issues to let us know when features don't work as expected.
    • Participate in the Fabric8 Kubernetes Client GitHub discussions.
    • Send pull requests for bug fixes and enhancements.
    • Chat with us on the Fabric8 Kubernetes Java client Gitter channel.
    • Ask Fabric8 related questions on StackOverflow.
    • Follow us on Twitter.
    Last updated: February 22, 2024

    Recent Posts

    • AI meets containers: My first step into Podman AI Lab

    • Live migrating VMs with OpenShift Virtualization

    • Storage considerations for OpenShift Virtualization

    • Upgrade from OpenShift Service Mesh 2.6 to 3.0 with Kiali

    • EE Builder with Ansible Automation Platform on OpenShift

    What’s up next?

    The evolution of microservices and containers in recent years significantly changed the way we design, develop, and run software. In Kubernetes Patterns, you'll learn to create cloud-native applications with Kubernetes as a runtime platform and build container images directly within the cluster.

    Get the e-book
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue