Why Not a Native Solver?
Your model outgrew the built-in solvers and now you need something stronger. That sounds like one decision, but it is actually a stack of obligations you are inheriting — and most of them have nothing to do with solving.
What you are really signing up for
JNI and native binaries. The solver is C or C++ code called through JNI or the Foreign Function Interface. A segfault in native code takes down the JVM with no stack trace you can read. Debugging requires tools and skills that have nothing to do with Java, and the failure modes are different from anything else in your application. Every platform you deploy to needs its own binary, and every JDK upgrade is a compatibility question.
Container images. Your Dockerfile was simple: a JDK base image and a JAR. Now it carries native libraries, OS-level dependencies, and architecture-specific binaries. You are building and maintaining multi-platform images for code you did not write, and a broken solver build blocks your release pipeline the same way a broken test does.
Licence servers. Most commercial solvers enforce their licence at runtime, either through a network call to a licence server or a licence file that has to be present in the container. That is a network dependency in production — one more thing to provision, monitor and explain to the people who own the infrastructure. If the licence server is unreachable, the solver does not start.
Security review. Native code running inside your application process is a different risk profile from pure Java. Someone in your organisation has to sign off on it, and they will have questions: where did the binary come from, who built it, what does it link against, and what access does it have. Every solver upgrade reopens that conversation.
Vendor lock-in. The moment you express your model in a solver-specific API — Gurobi’s, CPLEX’s, any of them — switching costs start compounding. Every constraint, every parameter, every callback is written against that vendor’s interface. Moving to a different solver later means rewriting the model, not just changing a dependency.
The cost no one quotes
Commercial solver licences are expensive. Pricing is typically quote-gated, but the numbers are not small — tens of thousands per year for a single production deployment is normal, and it scales with cores, machines, or users depending on the vendor. Everyone evaluating a commercial solver knows that part.
What they do not account for is that the licence fee is only the beginning. The engineering hours — building platform-specific images, debugging across the JNI boundary, maintaining licence server infrastructure, defending native binaries in security reviews, and keeping all of it working as JDK versions and solver versions move independently — are a cost that recurs every sprint. It does not appear on any vendor’s pricing page, and it is almost never part of the evaluation.
The total cost of putting a commercial native solver into a Java application in production, and keeping it there, routinely exceeds the licence fee within the first year. The licence is the line item people compare. The engineering is the cost that actually matters, and most of it is invisible until the team is already committed.
Do you actually need the strongest solver on the market?
Most models do not. The gap between ojAlgo’s built-in solvers and the top commercial offerings is large, but the problems that genuinely require the upper end of that range are rarer than the vendors’ marketing suggests. A well-maintained suite of open-source solvers — stronger than anything pure Java can offer, tuned and kept current — is more than enough for the great majority of production LP, QP and MIP workloads.
Paying for the strongest solver available when a capable one will do is the same mistake as over-provisioning any other part of your infrastructure — except this one also brings all the complexity described above.
An alternative
The problem is not that native solvers exist. The problem is that they end up inside your application.
The Optimisation Service puts the native solvers in a server you deploy in your own cluster, and your application stays pure Java — one Maven dependency, no JNI, no native binaries, no licence servers in your process. The model code you already have does not change.
The solver stack is assembled from permissively licensed open source solvers. No commercial solver licence is required, and none is included — there is nothing to buy from anyone else. The server runs without a licence key in a restricted mode, free forever — enough to put a real model through before deciding anything.
The question is not whether you need a stronger solver. It is whether the solver needs to live in your application.