Java Development

    Java development and modernization services

    Your Java applications still run the business, but they are stuck on an old JDK, an old framework or an application server nobody wants to touch. Agnotic Technologies builds new Java services and upgrades existing ones as an outsourced team, with tests at every step.

    Java LTS upgradesjavax to jakartaSpring Boot 3Off the app server

    Trusted by global innovators

    Benchmark
    Chibasco
    Fundency
    Lantimer
    Lauren
    Lera
    One Minute
    Pento Pix
    TAP
    Xtrium
    Healthevolve
    Benchmark
    Chibasco
    Fundency
    Lantimer
    Lauren
    Lera
    One Minute
    Pento Pix
    TAP
    Xtrium
    Healthevolve
    Benchmark
    Chibasco
    Fundency
    Lantimer
    Lauren
    Lera
    One Minute
    Pento Pix
    TAP
    Xtrium
    Healthevolve
    Benchmark
    Chibasco
    Fundency
    Lantimer
    Lauren
    Lera
    One Minute
    Pento Pix
    TAP
    Xtrium
    Healthevolve

    Java delivery

    What does a Java development and modernization engagement cover?

    A Java development and modernization engagement builds new Java services and brings existing ones up to date: moving to a current Java LTS release, changing javax packages to jakarta, upgrading to Spring Boot 3 and retiring legacy application servers for containers. Agnotic Technologies delivers the work as an outsourced team, with testing at every step.

    To hire individual Java developers into your own team, see our Java developers page. This page is for Java work delivered as a project: an upgrade, a new service or a move off an application server.

    Java upgrades rarely fail on the language. They fail on removed modules, renamed packages and libraries that dropped old versions, so we map those before changing anything.

    Upgrade paths

    What breaks on each Java upgrade path?

    Where you start decides the work. We place every application in one of these rows during the assessment.

    FromBlocking changesTypical fixTest focus
    Java 8 to 11 or laterJava EE and CORBA modules removed from the JDK (JAX-WS, JAXB, JAF, Common Annotations, CORBA, JTA)Add the standalone libraries as dependenciesFull suite on the new JDK before any code style changes
    Java 11 to 17 or 21Stronger encapsulation of JDK internals; old bytecode libraries and build plugins failUpgrade build tools and libraries firstReflection-heavy code such as serialization, mocking and proxies
    Java EE 8 to Jakarta EE 9 or laterEnterprise packages renamed from javax.* to jakarta.*Automated package rewrite, then fix libraries that still import javaxDeployment on the new server and every integration
    Spring Boot 2 to 3Java 17 minimum; Jakarta EE APIs replace Java EEUpgrade to Spring Boot 2.7 first, then to 3Security configuration, data access and observability
    Application server to containersServer-managed data sources, JNDI lookups, EAR packaging, session replicationExecutable JAR in a slim image; configuration from the environmentSessions, scaling and startup under load

    Which Java version should you be on?

    A current long-term support release. Oracle names Java SE 8, 11, 17, 21 and 25 as LTS releases and plans a new one every two years.

    For most applications we upgrade straight to the newest LTS release your libraries support, rather than stepping through every version. Where a library holds you back, we go to the highest LTS release it supports and plan the next step.

    Staying on Java 8 is possible for a while with paid support from a JDK vendor, but frameworks keep moving: Spring Boot 3 already needs Java 17.

    Method

    How do we upgrade a Java application without a rewrite?

    Six steps that keep the application shippable throughout.

    1. Inventory

      JDK version, build tool, frameworks, libraries and the server each application runs on.

    2. Build on the new JDK

      Compile and run the existing tests on the target JDK in a branch, and list what breaks.

    3. Fix libraries before code

      Upgrade build plugins, test libraries and frameworks to versions that support the target.

    4. Rename packages

      Rewrite javax enterprise imports to jakarta with a tool, then fix what the tool cannot.

    5. Add missing tests

      Write characterization tests around areas the suite does not reach, before risky changes.

    6. Run side by side

      Deploy old and new builds to the same test environment and compare behavior and performance.

    Application servers

    How do we move off a legacy application server?

    What changes when an application stops depending on a full Java EE server.

    • Data sources and connection pools move from server configuration into the application
    • JNDI lookups are replaced with dependency injection and environment configuration
    • EAR and WAR packages become executable JARs in container images
    • Server-managed sessions move to a shared store, so instances can scale out
    • Scheduled jobs and message listeners move to the framework or a managed queue
    • Logs and metrics go to your monitoring stack instead of the server's console

    Failure points

    Common Java upgrade failure points

    What we see on stalled upgrades, and how we avoid it.

    Challenge

    One library has no release that supports the target JDK.

    Agnotic approach

    We find it in the inventory, then replace it, fork it or upgrade to the highest JDK it supports first.

    Challenge

    javax and jakarta classes end up mixed in one build.

    Agnotic approach

    Dependency checks in the build fail on any remaining javax enterprise import.

    Challenge

    The upgrade branch lives for months and drifts from main.

    Agnotic approach

    Small upgrades merge to main behind build flags, so feature work and the upgrade move together.

    Challenge

    Tests pass but production behaves differently.

    Agnotic approach

    Old and new builds run side by side on production-like data before cutover.

    Challenge

    Startup and memory change on the new JDK.

    Agnotic approach

    We measure startup, memory and throughput before and after, and tune settings for containers.

    What Java work do we take on?

    Delivery work, not individual developer placement.

    New Spring Boot services

    APIs and services on current Java and Spring Boot, with tests and deployment pipelines from the first release.

    JDK and framework upgrades

    Java 8 or 11 to a current LTS release, and Spring Boot 2 to 3, with the steps above.

    Application server retirement

    Moving from full application servers to containers on your cloud or cluster.

    Batch and integration jobs

    Spring Batch jobs, message consumers and file integrations rebuilt or upgraded.

    API layers over legacy systems

    Modern APIs in front of older Java systems, so new apps do not call them directly.

    Java consulting and code review

    An assessment of your Java estate with an upgrade plan, before any build work.

    Engagement models

    Java outsourcing, Java consulting or a dedicated team?

    Three ways clients bring Java work to us.

    Java outsourcing

    We deliver a defined project, such as an upgrade or a new service, and own the delivery.

    Java consulting

    A short assessment: inventory, blockers, a target version and a plan your team can follow.

    Dedicated team

    A team that stays on your Java systems over time, under your product lead.

    Rescue of a stalled upgrade

    We pick up an upgrade branch that has drifted, and bring it to release.

    Java for startups

    A first Spring Boot backend, scoped as a fixed first release.

    Regulated Java systems

    Upgrades for systems with audit and validation needs, with the test evidence kept.

    Scope and cost

    What drives the cost of Java outsourcing?

    We do not publish prices. These are what we size in the assessment.

    Number of applications

    How many services and libraries share the upgrade.

    Starting point

    The JDK, framework and server each application runs on today.

    Library blockers

    How many dependencies need replacing or forking.

    Test coverage

    Whether the suite can prove the upgrade, or characterization tests come first.

    Hosting change

    Whether the move includes containers and a new platform.

    Parallel feature work

    Whether your team keeps shipping features during the upgrade.

    Platforms

    Java platforms and practices we work with

    The releases and specifications our upgrades target.

    Java SE LTSJakarta EESpring Boot 3JUnit 5OpenAPIOCI images
    Facts and sources

    Facts behind Java development and modernization

    Release and platform facts that set the upgrade plan, each linked to its primary source.

    Engagement

    How does a Java engagement work?

    Three stages, each with a clear output.

    1.

    Scoping call and assessment

    Inventory of applications, blockers and tests, with a target version and plan.

    Assess
    2.

    First application upgraded

    One application taken through every step to release, proving the pattern.

    Build
    3.

    Remaining applications and support

    The rest of the estate, then support and the next LTS upgrade when it comes.

    Support

    Frequently Asked Questions

    With Java outsourcing we own a defined piece of delivery, such as an upgrade or a new service, including planning and testing. Hiring developers adds people to your team under your management; that is covered on our Java developers page.