Hire Java developers
Java runs a large share of the systems that move money and cannot fail, and hiring for it means separating language familiarity from experience of the systems it is usually found in.
What Java actually is
Java is a statically typed language running on the Java Virtual Machine, with an ecosystem overseen through an open process and builds available from several vendors. It has a long support cycle, strong backward compatibility, and a reputation for verbosity that is less deserved than it was a decade ago. Where it dominates is systems that are expected to run for many years under load: banking, insurance, telecommunications, logistics and large enterprise back ends.
The commercially important fact about Java is that backward compatibility has been taken seriously for a very long time. Code written years ago generally still runs, which is why so much of it is still in production and why so much Java work is maintenance and modernisation rather than greenfield development. A Java hire is far more often joining a system with history than starting something new.
That history is the thing to interview for. The language is not hard to learn and the frameworks are well documented. What is hard is working safely inside a large codebase that predates the person touching it, where the tests are partial, the original authors have left, and the cost of a regression is measured in money rather than in inconvenience. Candidates who have only built new services tend to underestimate this.
The part that separates seniors from mid-levels
The virtual machine is the thing that distinguishes senior Java developers. Memory is managed by a garbage collector with tunable behaviour, and the choices there have direct consequences for latency. A developer who has operated a latency-sensitive Java service can talk about pause times, heap sizing, and the difference between throughput and latency as goals. One who has not will treat memory as something that takes care of itself, which is true right up until it is the incident.
Concurrency is the second area, and Java gives you real threads and real shared memory, which means real data races. The memory model is genuinely subtle: whether one thread sees another's write depends on rules most developers have never read. Experienced candidates prefer the higher-level concurrency utilities over hand-rolled synchronisation, know why double-checked locking was famously wrong, and treat shared mutable state as something to design away rather than to guard.
The third is the framework layer, which in practice means Spring for most commercial work. Spring's dependency injection and auto-configuration remove a great deal of wiring and hide a great deal of behaviour. The developer who can explain what the framework is actually doing at startup, and can debug a context that fails to initialise, is a different proposition from the one who can only work when the annotations behave as expected.
Where Java is used
The label “Java developer” covers several jobs that share a technology and little else. These are the settings the work usually turns up in, and the one you are hiring into should shape the whole process, because the judgement each demands is different.
Financial services
Core banking, payments, settlement and trading systems, where correctness and auditability outrank development speed.
Enterprise back ends
Large internal systems in insurance, telecoms, healthcare and logistics, often integrating with systems older than the team.
Microservice estates
Spring Boot services deployed in containers, typically the modernisation target for an older monolith.
Data infrastructure
Kafka, Spark, Elasticsearch and similar systems are themselves written on the JVM, and operating them well is a Java-adjacent skill.
Android applications
Historically Java, now largely Kotlin, but a great deal of existing Android code remains Java.
Legacy modernisation
Moving applications off unsupported versions, off application servers, or out of monoliths, which is a large share of the market.
If a candidate's experience sits in a different row of that list from the work you have, that is not a reason to reject them, but it is the thing to probe. Ask what would be different about their approach in your setting. Someone who can answer that has transferable judgement. Someone who says it would be much the same has probably not thought about it.
Which Java versions are still supported
Java publishes long-term support releases on a predictable cycle with clearly dated support windows, which makes the supported set unambiguous and upgrade planning unusually straightforward.
The table is generated from public release data rather than written by hand, so it states what is supported today rather than what was true when any given article was published. Of the 8 most recent release lines, 2 are still maintained and 6 have passed their published end-of-life date. That distinction is the practical one when you read a job specification: a requirement written against a line that is now out of support tells you the specification is older than the codebase it describes, and it is worth asking which of the two the new developer will actually work in.
| Release | Released | End of life | Status | Latest patch |
|---|---|---|---|---|
| 26 | 2026-03-23 | 2026-09-15 | End of life | 26.0.2.1+1 (2026-08-25) |
| 25 (LTS) | 2025-09-22 | 2031-09-30 | Maintained, long-term support | 25.0.4.1+1 (2026-08-19) |
| 24 | 2025-03-20 | 2025-09-16 | End of life | 24.0.2+12 (2025-07-17) |
| 23 | 2024-09-17 | 2025-03-18 | End of life | 23.0.2+7 (2025-01-23) |
| 22 | 2024-03-20 | 2024-09-17 | End of life | 22.0.2+9 (2024-07-17) |
| 21 (LTS) | 2023-10-10 | 2029-12-31 | Maintained, long-term support | 21.0.12.1+1 (2026-08-19) |
| 20 | 2023-03-23 | 2023-09-19 | End of life | 20.0.2+9 (2023-07-21) |
| 19 | 2022-09-26 | 2023-03-31 | End of life | 19.0.2+7 (2023-01-20) |
Source: endoflife.date public release data, read 2026-09-25.
Two questions follow from this table in an interview. The first is which line the candidate has most recently shipped against, because someone whose last production work was on an unsupported line has not had to deal with the changes since. The second is how they have handled an upgrade. Version migrations are where you see whether a developer reads release notes, writes characterisation tests before changing anything, and knows how to stage a rollout, or whether they upgrade in place on a Friday and hope.
The toolchain around it
Nobody hires for Java alone. The surrounding tools are where most of the day-to-day work happens, and a gap in any of them costs more time than a gap in the core library. This is the set that turns up most often on real job specifications alongside it.
- Spring Boot
- The default framework for commercial Java services, supplying configuration, web, data access and security.
- Maven or Gradle
- Build and dependency management. Which one a team uses says something about its age and its tolerance for build complexity.
- Hibernate or JPA
- Object-relational mapping, and the most common source of unexpected query behaviour.
- PostgreSQL or Oracle
- The data store. Oracle in older enterprise estates, PostgreSQL in most newer work.
- JUnit with Testcontainers
- Testing, with real dependencies in containers rather than mocks where it matters.
- Kafka
- Event streaming, extremely common in the estates where Java dominates.
- Micrometer and OpenTelemetry
- Metrics and tracing, including the garbage collection behaviour that matters under load.
- A container platform
- Kubernetes or a managed equivalent, where modern Java services are deployed.
Related skills that frequently appear on the same specification: Spring Boot, SQL, Android and Kotlin, AWS, Kubernetes.
What to test in an interview
These are the topics that separate candidates in practice. Each one is given with why it discriminates, what a strong answer sounds like, and the response that should make you slow down. None of them requires a whiteboard.
Garbage collection and latency
The clearest divider between someone who has operated a Java service and someone who has only written one.
- Strong answer: Can describe tuning heap or collector choice for a latency target, and has read a pause-time graph during an incident.
- Warning sign: Treats memory as automatic and has never seen a pause matter.
Concurrency and shared state
Java gives you enough rope, and the failures are intermittent and expensive.
- Strong answer: Prefers the concurrency utilities and immutability, can explain why a field needs to be volatile, and designs shared state away.
- Warning sign: Reaches for synchronized on everything, or believes thread safety is a property of a class name.
What Spring does at startup
Separates framework understanding from annotation familiarity.
- Strong answer: Can explain component scanning, bean lifecycle and auto-configuration, and has debugged a context failure.
- Warning sign: Cannot explain why a bean was not created, beyond checking that the annotation is present.
ORM behaviour and generated SQL
Hibernate hides the database until it surprises you.
- Strong answer: Inspects generated SQL, understands lazy loading and the N plus one pattern, and knows when to drop to native queries.
- Warning sign: Has never looked at what queries the ORM emits.
Working in a large inherited codebase
Most Java work is this, and most interviews do not test it.
- Strong answer: Describes writing characterisation tests before changing behaviour, and changing things in small reversible steps.
- Warning sign: Proposes a rewrite as the first response to an unfamiliar codebase.
Version and dependency upgrades
A large share of real Java work, and genuinely risky in an old estate.
- Strong answer: Has moved a real application across major versions and can describe what broke and how they staged it.
- Warning sign: Has only worked on applications that were already current.
Testing strategy in an enterprise system
Reveals whether they understand the cost of a regression here.
- Strong answer: Integration tests against real dependencies, characterisation tests around legacy behaviour, and clear views on what not to test.
- Warning sign: Heavy mocking that tests the mocks, or a coverage number quoted as a goal.
Warning signs in a Java codebase
The fastest way to read a candidate is to ask what they have found wrong in code they inherited. These are the patterns that come up most often, what they cost, and what fixing them looks like. A developer who recognises three or four of these from their own experience is worth more than one who can recite the documentation.
The N plus one query through the ORM
- What you see: A loop over entities touching a lazily loaded relation each time.
- What it costs: Hundreds of round trips, latency that grows with data, and a problem invisible in development.
- The fix: Fetch joins or entity graphs, and log generated SQL in development so the pattern is visible when written.
Catching Exception and continuing
- What you see: Broad catch blocks that log and carry on.
- What it costs: Failures are hidden, the system continues in an inconsistent state, and the real cause is lost.
- The fix: Catch what you can handle. Let the rest propagate to a boundary that decides deliberately.
Shared mutable state guarded by hope
- What you see: Fields mutated from several threads with partial or no synchronisation.
- What it costs: Intermittent corruption that cannot be reproduced and is usually blamed on something else.
- The fix: Prefer immutability and the concurrency utilities. Where mutation is required, confine it to one owner.
The god service
- What you see: A single class of several thousand lines that every feature touches.
- What it costs: Every change risks everything, and no two developers can work in the area at once.
- The fix: Extract along genuine seams, with characterisation tests written first so behaviour is provably preserved.
Configuration scattered across environments
- What you see: Behaviour differing between environments through properties nobody has catalogued.
- What it costs: Works in staging, fails in production, and the difference takes days to find.
- The fix: Centralise configuration, make it explicit, and fail fast at startup when something required is missing.
Running on an unsupported Java version
- What you see: A production application on a release past its support window.
- What it costs: No security patches, libraries that will no longer publish compatible versions, and a growing upgrade cliff.
- The fix: Move to a supported long-term release. The work is usually smaller than the fear, and it compounds if deferred.
What each level can own
Job titles are not comparable between companies, so it is more useful to describe levels by what a person can be left to own without supervision. These are the boundaries we use when we assess a Java developer.
- Junior
- Implements features inside an existing service under review. Needs guidance on transactions, concurrency and ORM behaviour.
- Mid-level
- Owns a service or module including its tests and its database interactions. Can debug a Spring context and read a stack trace properly.
- Senior
- Owns service boundaries, transaction and consistency design, and performance under load including collector behaviour. Can modernise a legacy application incrementally.
- Staff
- Owns the estate: version and dependency policy, the decomposition strategy, the contracts between services, and the case for what should not be changed.
How the work is usually scoped
Team shape follows the kind of work, not the headcount you happen to have budget for. These are the shapes that come up most often and the constraint that actually governs each one.
New Spring Boot service
- Usual team: Two developers, senior-led initially.
- What governs it: Straightforward when the domain is clear. The integrations with existing systems are what actually take the time.
Monolith decomposition
- Usual team: Two to three developers plus someone who knows the existing system.
- What governs it: Governed by data entanglement. Splitting the database is the project; splitting the code is the easy half.
Version upgrade across an estate
- Usual team: One senior developer plus the owning teams.
- What governs it: Scoped by dependency count and test coverage. Several versions behind with thin tests is a multi-quarter effort.
Latency remediation
- Usual team: One senior developer with production access, time-boxed.
- What governs it: Starts with measurement: collector pauses, query plans, thread contention. Rarely where the team expected.
Team augmentation on an enterprise system
- Usual team: One to three developers joining an existing team.
- What governs it: Constrained by review capacity and by domain knowledge transfer, not by headcount.
Migration work you may actually be hiring for
A large share of Java work is not new development. It is moving an existing system from one state to another while it stays in service. These are the migrations that come up most often, and each one asks for a different kind of experience from the person you hire.
An unsupported Java version to a current long-term support release
- Why teams do it: Security patches and library compatibility. Increasingly also a procurement and audit requirement.
- What to watch: The module system and removed internal APIs break older libraries. Inventory dependencies first; the ones with no maintained release are the real decision points.
An application server deployment to Spring Boot in containers
- Why teams do it: Simpler deployment, independent scaling and an end to shared-container configuration problems.
- What to watch: Anything relying on server-managed resources such as connection pools, transactions or security realms needs an explicit replacement. Move one application at a time and keep the old path live.
A monolith to services
- Why teams do it: Independent deployment and scaling, usually driven by team structure rather than by technology.
- What to watch: The database is the project. Extract a service with its own data before extracting a second one, and expect to run both paths in parallel for longer than planned.
Java to Kotlin on the JVM
- Why teams do it: Less ceremony, null safety in the type system, and better ergonomics for the same runtime.
- What to watch: They interoperate, so this is incremental by nature. Mixed codebases are normal and fine; forcing a full conversion rarely pays for itself.
Migration work rewards a different temperament from greenfield work. The useful question in an interview is not whether someone has done the specific migration you face, but whether they have ever run one incrementally: behind a flag, with both paths live, and with a way back. Developers who have only done big-bang cutovers tend to propose them again.
What a good brief for this role contains
Most of the time lost in hiring a Java developer is lost before anyone is interviewed, in the gap between what the brief says and what the team actually needs. These are the points that, for this technology specifically, change who the right candidate is. A brief that answers them can be matched in days. One that does not produces a shortlist that looks reasonable and converts badly.
- Which Java version the codebase targets, and whether an upgrade is part of the work.
- Whether this is new development, maintenance of an existing system, or a modernisation, since these attract very different people.
- What the framework and persistence layer are, and how old the oldest part of the codebase is.
- What the cost of a defect is in this domain, because that changes how the work should be done and who should do it.
- Whether the system integrates with older enterprise systems, and whether documentation or people with that knowledge still exist.
- Whether the person will be on call for what they build.
If you cannot answer some of these yet, that is normal and it is still worth writing down which ones are open. An unknown that is named can be worked around. An unknown that is papered over in a job specification turns into a rejected shortlist and a restart four weeks later.
What the US market pays for this work
Java work is counted by the US Bureau of Labor Statistics under Software Developers. That classification is broader than the technology itself, so treat the figures as the shape of the market a Java developer is hired into rather than as a rate card for the skill. Across the United States the Bureau counts 1,687,890 people in this occupation, with a median annual wage of $135,980.
The spread matters more than the midpoint. The 90th percentile is about 2.6 times the 10th, which is a wide band for a single occupation and tells you that the title on its own carries very little pricing information. Two people described as a Java developer can sit at $82,460 and $214,670 in the same national dataset. When a budget is set from a median without asking which end of that range the work actually needs, the hire that follows is usually the wrong one in one direction or the other.
Related classifications are worth reading alongside it, because teams hiring for Java frequently end up recruiting against these titles too:
| Occupation | Employed | 25th percentile | Median | 75th percentile | 90th percentile |
|---|---|---|---|---|---|
| Software Developers | 1,687,890 | $105,210 | $135,980 | $171,980 | $214,670 |
| Computer Programmers | 92,230 | $75,850 | $100,390 | $130,680 | $160,460 |
| Computer Systems Analysts | 519,530 | $82,860 | $105,850 | $134,110 | $167,710 |
Source: BLS Occupational Employment and Wage Statistics, May 2025. Figures cover all US employers and are not FuturByte rates.
These are employer-side wage figures for people on a US payroll. They exclude employer taxes, benefits, recruitment cost and the months a seat sits empty, all of which are real and none of which appear in a salary line. The useful way to read the table is as the cost of the alternative you are comparing against, not as a number to match.
How US metro markets compare for this role
The same job is priced very differently across the country. Ranked by median annual wage for Software Developers, the gap between the highest and lowest of the 28 metro areas covered here is a factor of about 1.7. San Jose sits at the top with a median of $213,110; Pittsburgh sits at the bottom with $124,500. A budget built from a national median will be wrong in both of those markets, in opposite directions.
| Metro area | Employed | Median wage | vs US median | Location quotient |
|---|---|---|---|---|
| San Jose, CA | 87,350 | $213,110 | +57% | 7.09 |
| San Francisco, CA | 69,030 | $186,640 | +37% | 2.68 |
| Seattle, WA | 92,770 | $167,280 | +23% | 4.10 |
| New York, NY | 121,000 | $166,830 | +23% | 1.17 |
| Boston, MA | 42,310 | $166,090 | +22% | 1.44 |
| San Diego, CA | 20,610 | $163,270 | +20% | 1.23 |
| Los Angeles, CA | 55,540 | $160,920 | +18% | 0.82 |
| Portland, OR | 18,260 | $156,000 | +15% | 1.39 |
| Washington, D.C. | 69,060 | $154,930 | +14% | 2.03 |
| Baltimore, MD | 16,850 | $138,900 | +2% | 1.14 |
| Denver, CO | 27,010 | $137,610 | +1% | 1.55 |
| Charlotte, NC | 20,820 | $135,920 | 0% | 1.41 |
| Chicago, IL | 40,370 | $134,380 | -1% | 0.82 |
| Austin, TX | 31,960 | $134,120 | -1% | 2.28 |
| Dallas-Fort Worth, TX | 67,030 | $133,290 | -2% | 1.52 |
| Philadelphia, PA | 28,480 | $133,040 | -2% | 0.91 |
| Atlanta, GA | 36,300 | $132,960 | -2% | 1.16 |
| Raleigh, NC | 12,580 | $132,770 | -2% | 1.56 |
| Miami, FL | 18,900 | $132,650 | -2% | 0.62 |
| Phoenix, AZ | 29,380 | $131,750 | -3% | 1.14 |
| Minneapolis-St. Paul, MN | 27,410 | $130,920 | -4% | 1.29 |
| Detroit, MI | 24,870 | $130,760 | -4% | 1.20 |
| Tampa, FL | 14,230 | $130,450 | -4% | 0.91 |
| Orlando, FL | 13,440 | $129,620 | -5% | 0.88 |
| Salt Lake City, UT | 19,040 | $129,600 | -5% | 2.12 |
| Houston, TX | 22,940 | $129,440 | -5% | 0.64 |
| Kansas City, MO | 12,160 | $124,990 | -8% | 1.02 |
| Pittsburgh, PA | 10,320 | $124,500 | -8% | 0.85 |
Location quotient compares how concentrated this occupation is in the metro against the national average. A value above 1 means the metro has more of this work than its size would predict.
The location quotient column is the more useful one for hiring. A high median tells you what a role costs; a high quotient tells you whether the people exist. San Jose, San Francisco, Seattle, Washington, D.C., Denver, Austin each have a quotient of 1.5 or above, meaning the work is concentrated there well beyond what the size of the local economy would predict. Those are the markets where a search is likely to be quick and competitive at the same time, and where a counter-offer is most likely to take a candidate off the table late in the process.
The opposite case is worth planning for too. In a metro with a low quotient, the total pool is small even when wages look reasonable, so the realistic options are to widen the search radius, accept a longer time to hire, or bring the capability in from outside the local market entirely. That last option is what most teams are weighing when they come to us.
Hiring risks worth naming
Every one of these has produced a bad hire somewhere. They are written down so that the process tests for them deliberately rather than discovering them in month three.
Greenfield-only experience. Most Java work is inherited. Ask how they would approach a large codebase with partial tests and no original authors.
Framework familiarity without JVM understanding. Ask about memory and collector behaviour. Spring experience does not imply it and production will eventually require it.
No experience of the domain's failure cost. In payments or healthcare, a regression is not an inconvenience. Ask what they do differently when correctness outranks speed.
Resistance to working in older code. Ask directly how they feel about maintenance. Someone who only wants greenfield will be unhappy and will leave.
Hiring Java developers by metro area
Wages for this occupation vary more between US metro areas than most budget models assume. Each page below sets out the published employment and wage figures for that market, how it compares with the national picture, and what the local industry mix means for the kind of Java developer who will be available.
- New York, NY $166,830 median
- Seattle, WA $167,280 median
- San Jose, CA $213,110 median
- Washington, D.C. $154,930 median
- San Francisco, CA $186,640 median
- Dallas-Fort Worth, TX $133,290 median
- Los Angeles, CA $160,920 median
- Boston, MA $166,090 median
- Chicago, IL $134,380 median
- Atlanta, GA $132,960 median
- Austin, TX $134,120 median
- Phoenix, AZ $131,750 median
- Philadelphia, PA $133,040 median
- Minneapolis-St. Paul, MN $130,920 median
- Denver, CO $137,610 median
- Detroit, MI $130,760 median
- Houston, TX $129,440 median
- Charlotte, NC $135,920 median
- San Diego, CA $163,270 median
- Salt Lake City, UT $129,600 median
- Miami, FL $132,650 median
- Portland, OR $156,000 median
- Baltimore, MD $138,900 median
- Tampa, FL $130,450 median
- Orlando, FL $129,620 median
- Raleigh, NC $132,770 median
- Kansas City, MO $124,990 median
- Pittsburgh, PA $124,500 median
Frequently asked questions
Is Java still a reasonable choice for new systems?
Yes, particularly where a system is expected to run for a decade, handle serious load, and be maintained by people who have not met its authors. Its strengths are stability, tooling, operational maturity and a very large hiring pool. Its weakness is that it is rarely the fastest way to get a first version in front of users.
Should we hire Java or Kotlin developers?
For work on the JVM, treat them as one pool with a preference rather than two. A competent Java developer picks up Kotlin quickly, and most Kotlin developers read Java fluently because they have to. Insisting on Kotlin-only experience narrows the pool considerably for a gap that closes in weeks.
Our application is on an old Java version. How urgent is upgrading?
Urgent if it is past its support window, because that means no security patches and a shrinking set of libraries that will still support it. The upgrade is usually less painful than teams expect, and the pain is concentrated in dependencies rather than in the language. Deferring it makes it strictly worse, because each year adds versions to cross.
Why is our Java service using so much memory?
Usually because the heap has been sized generously and the collector has no reason to work harder, which is not in itself a problem. It becomes a problem when pause times affect latency or when the container limit is reached. The diagnosis is collector logs and a heap dump, and it is specialist work worth an experienced person for a few days rather than a general one for a few weeks.
Should we break up our Java monolith?
Only for a reason you can state. Good reasons are independent deployment, independent scaling, and independent teams. Bad reasons are that monoliths are unfashionable. Decomposition moves complexity from inside a process to between processes, where it is harder to debug, and the database is nearly always the hard part.
Is Spring Boot required, or could we use something lighter?
Lighter frameworks exist and are good. Spring Boot's practical advantage is the hiring pool and the fact that almost any problem you meet has been met before. If you have a specific reason such as startup time in a serverless context, alternatives are worth considering. Otherwise the ecosystem advantage is substantial.
How do we interview for enterprise Java rather than general Java?
Ask about the last unfamiliar codebase they had to change safely, about a production incident they diagnosed, and about a version or dependency upgrade they ran. Those three questions separate people who have worked in long-lived systems from people who have only built new ones, and the difference matters more in Java than in most ecosystems.
What does a Java developer need from us on day one?
A build that runs locally without tribal knowledge, access to a realistic database, and a named person who knows why the odd parts of the system are odd. That last one is the constraint in most enterprise estates, and it is the reason onboarding takes weeks rather than days.