Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

Write operators in Java with JOSDK, Part 4: Upgrading strategies

September 19, 2023
Christophe Laprun
Related topics:
JavaKubernetesOperatorsQuarkus
Related products:
Red Hat build of QuarkusRed Hat OpenShift

    Java Operator SDK(JOSDK) is an open source project that aims to simplify the task of creating Kubernetes operators using Java. Container Solutions started the project, and Red Hat is now a major contributor. The JOSDK project now lives under the Operator Framework umbrella, which is a Cloud Native Computing Foundation (CNCF) incubating project.

    The first article in this series introduced JOSDK and explained why it could be interesting to create operators in Java. The second article showed how the JOSDK Quarkus extension quarkus-operator-sdk, also called QOSDK, facilitates the development experience by taking care of managing the Custom Resource Definition automatically. The third article focused on requirements for implementing the reconciliation logic for the example operator you build in this series. Many things have changed since the third installment of this series. This article will thus focus on updating the code to the latest versions and provide upgrading strategies.

    Where things stand

    You implemented a simple operator exposing your application outside the cluster via an Ingress, creating the associated Deployment and Service along the way. However, it has been a while since the last part of this blog series and many things have changed. When the third article was written, QOSDK was in version 3.0.4. Now it is up to 6.3.0. Quarkus has also been updated. How can you update your operator to use more recent versions, and what are possible strategies to update your code?

    How to use Quarkus update

    Upgrading a project is always a tricky proposition, especially when there is a wide gap between the old and new versions. Quarkus can help you with this task, though it might not work in all cases. In this case, you want to migrate from Quarkus 2.7.3.Final to the latest version, which at the time of writing this article, is 3.2.4.Final. You can use the update command that Quarkus provides. If you have the quarkus command line tool, you might want to upgrade it first and then simply run quarkus update.

    Otherwise, using maven only, you can run:

    mvn io.quarkus.platform:quarkus-maven-plugin:3.2.4.Final:update -N

    The complete procedure is detailed in the related Quarkus guide.

    In your case, you should notice that the update procedure fails with an error when the command attempts to check the updated project as follows:

    [INFO] [ERROR] [ERROR] Some problems were encountered while processing the POMs:
    [INFO] [ERROR] 'dependencies.dependency.version' for io.quarkiverse.operatorsdk:quarkus-operator-sdk-csv-generator:jar is missing. @ line 38, column 17

    Updating outdated QOSDK dependency

    The problem occurs because this dependency doesn’t exist anymore. Though the project actually doesn’t need this dependency at this point, it is included by default when bootstrapping a QOSDK project using the operator-sdk CLI and allows for automatic generation of Operator Lifecycle Manager (OLM) bundles. OLM enables you to manage the lifecycle of operators on clusters in a more principled way. We might discuss this feature in greater detail in a future article.

    There are two ways to fix your project. If you’re not interested in the feature, you can remove the dependency, or change it to the correct one. This dependency doesn’t exist in its previous form anymore because it has been renamed to better reflect its expanded scope. It initially focused solely on the ClusterServiceVersion part of OLM bundles, but now extends to generating complete bundles. The feature was actually disabled using quarkus.operator-sdk.generate-csv=false in the application.properties file.

    The new dependency name is quarkus-operator-sdk-bundle-generator. So use that if you want to use the OLM generation feature. Note that you will also need to change the associated property name to activate the feature. You’ll see a warning in the logs that the property doesn’t exist if you don’t, and the OLM generation will be activated by default. The new property is named quarkus.operator-sdk.bundle.enabled.

    After making these changes, you can re-run the update command. It should now succeed, with an output similar to the following:

    [INFO] Detected project Java version: 11
    [INFO] Quarkus platform BOMs:
    [INFO]         io.quarkus:quarkus-bom:pom:3.2.4.Final ✔
    [INFO] Add:    io.quarkus.platform:quarkus-operator-sdk-bom:pom:3.2.4.Final
    [INFO]
    [INFO] Extensions from io.quarkus:quarkus-bom:
    [INFO]         io.quarkus:quarkus-micrometer-registry-prometheus ✔
    [INFO]
    [INFO] Extensions from io.quarkus.platform:quarkus-operator-sdk-bom:
    [INFO] Update: io.quarkiverse.operatorsdk:quarkus-operator-sdk-bundle-generator:6.3.0 -> remove version (managed)
    [INFO] Update: io.quarkiverse.operatorsdk:quarkus-operator-sdk:6.3.0 -> remove version (managed)

    Strategies for QOSDK and Quarkus updates

    Now you can see that you can actually simplify things even further. It is advising you to add the io. quarkus.platform:quarkus-operator-sdk-bom:pom:3.2.4.Final dependency. Indeed, QOSDK has been added to the Quarkus platform, making it easier to consume from a given Quarkus version. Switching to this BOM only allows you to decide which version of Quarkus to use, and the BOM will make sure you get the appropriate QOSDK version.

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.quarkiverse.operatorsdk</groupId>
                <artifactId>quarkus-operator-sdk-bom</artifactId>
                <version>${quarkus-sdk.version}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

    This project is currently using the QOSDK BOM with quarkus-sdk.version with the 3.0.4 value. You’ll also note that there is a quarkus.version property with the 2.7.3.Final value. Looking at the QOSDK BOM, you can see that there is also a Quarkus version property defined there, with the same quarkus.version name. Therefore, if you upgrade the QOSDK version, with the current setup, you need to make sure to also upgrade the Quarkus version in your project in such a way that is compatible with the version defined in the QOSDK BOM.

    Using the QOSDK BOM defined by the Quarkus platform (i.e., Using the io.quarkus.platform:quarkus-operator-sdk-bom artifact instead of the io.quarkiverse.operatorsdk:quarkus-operator-sdk-bom, note the different group identifier.) simplifies this aspect by making sure that both QOSDK and Quarkus versions are aligned. The downside of this is that using the QOSDK BOM directly from the QOSDK project, you have the Quarkus BOM automatically included in your project. The price for this, as previously explained, is that you need to make sure the versions are in sync.

    That said, you can also see that it is letting us know that there is a more recent version of the QOSDK extension (6. 3.0), which will only be available from the Quarkus platform starting with version 3.2.5.Final. Using the Quarkus platform, therefore, means that you’re not necessarily using the latest QOSDK version. This is, however, the version that is verified to work with the platform as a whole, so this is the more conservative option.

    If you wish to use the absolute latest version of QOSDK, you should use the BOM provided by QOSDK, but you will need to make sure to update the Quarkus version using the quarkus.version, while updating the QOSDK version using the quarkus-sdk.version property in your pom.xml file as previously done.

    Which approach to choose depends on your appetence for risk, or how you wish to manage your dependencies. Generally speaking, the Quarkus platform is updated frequently, and QOSDK versions are usually updated accordingly as needed. So the Quarkus platform is usually up-to-date when it comes to the latest QOSDK version. If you absolutely need the latest QOSDK version, upgrading from the Quarkus platform offerings, a patch or even a minor version should typically work with issues since QOSDK strives to maintain backwards compatibility between minor versions.

    Going the opposite direction, upgrading Quarkus to a minor version above (e.g., from 3.2.x to 3.3.x) might prove tricky since the Fabric8 Kubernetes client version used by that new Quarkus version might also have been updated to a new minor version. This has been known to bring API changes, so you might want to tread carefully with such updates.

    Actually, QOSDK issues debug-level warnings when it detects version mismatches (minor version and above, patch level mismatches considered safe) between Quarkus, JOSDK, and Fabric8 Kubernetes client. You can even configure it to fail a build by setting the quarkus.operator-sdk.fail-on-version-check to true. Please refer to the documentation for more details.

    It’s also worth repeating that since QOSDK bundles JOSDK, you do not need to worry about updating that dependency separately. One less thing to worry about.

    Adapting to Fabric8 Kubernetes client changes

    Now that the dependencies are sorted out, if you try to build now, you should get a compilation error due to an API change in the Fabric8 Kubernetes client:

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project expose: Compilation failure
    [ERROR] exposedapp-rhdblog/src/main/java/io/halkyon/ExposedAppReconciler.java:[63,33] cannot find symbol
    [ERROR]   symbol:   method withIntVal(int)
    [ERROR]   location: interface io.fabric8.kubernetes.api.model.ServicePortFluent.TargetPortNested<io.fabric8.kubernetes.api.model.ServiceSpecFluent.PortsNested<io.fabric8.kubernetes.api.model.ServiceFluent.SpecNested<io.fabric8.kubernetes.api.model.ServiceBuilder>>>

    This issue is easily fixed by changing the following line:

    .withNewTargetPort().withIntVal(8080).endTargetPort()

    to:

    .withNewTargetPort(8080)

    The Fabric8 Kubernetes client provides detailed notes for each release. It’s always a good idea to take a look at them, especially whenever a new minor version is released (here are the notes for the 6.8. 0 release, which does contain breaking changes). Another interesting resource is the cheat sheet, which contains a wealth of information on how to perform a wide variety of tasks using the client.

    That said, you should now be all set for this batch of updates!

    Summary

    While less focused on writing operators per se, this article still covered an important part of any software development: upgrading dependencies. Your operator should be now ready for improvements, which we will tackle in the next article. We will also discuss adding status handling and how to make your operator react to events that are not targeting primary resources.

    For reference, you can find the completed code for this part under the part-4 tag of the https://github.com/halkyonio/exposedapp-rhdblog repository.

    Related Posts

    • Write Kubernetes Operators with the Java Operator SDK

    • Write Kubernetes Operators in Java with the Java Operator SDK, Part 2

    • Writing Kubernetes Operators in Java with JOSDK, Part 3: Implementing a controller

    • How to implement Kubernetes operators with Java Operator SDK

    Recent Posts

    • Protect data offloaded to GPU-accelerated environments with OpenShift sandboxed containers

    • Case study: Measuring energy efficiency on the x64 platform

    • How to prevent AI inference stack silent failures

    • Preventing GPU waste: A guide to JIT checkpointing with Kubeflow Trainer on OpenShift AI

    • How to manage TLS certificates used by OpenShift GitOps operator

    What’s up next?

    Learn how to optimize Java for today’s compute and runtime demands with Quarkus. Quarkus for Spring Developers introduces Quarkus to Java developers, with a special eye for helping those familiar with Spring’s conventions make a quick and easy transition.

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

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    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
    © 2026 Red Hat

    Red Hat legal and privacy links

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

    Chat Support

    Please log in with your Red Hat account to access chat support.