I don't really get the need for GraalVM and especially native image part of it. JVMs now a days (incl. OpenJ9) start up fast enough on modern hardware anyways. Going through the complexity of native image generation seems like a solution in search of a problem.
I am sure you lose functionality with native image as well - reflection etc.
[Edit: I get the point about GraalVM itself just not the native image in the context of kubernetes. With GraalVM maybe they want to optimize better, allow various other languages to run on the JVM etc. None of that is Kuberenetes specific - not much of a memory or startup speed benefit unless I am missing something.]
Startup time doesn't matter for long-running applications.
It makes sense for things like lambda or knative ("serverless"). Also command-line applications (including tools you might put in CI).
Also, while the JVM starts quickly you also need to do class loading, which can take a while for complex applications with lots of classes. This is also pretty important when running a JVM-hosted language like Clojure which has quite a few classes of its own.
If you're starting jobs in response to queues, you want those jobs to start quickly. And if you're starting a lot of jobs, the less memory they consume, the more of them you can pack in your cluster and the less you need to autoscale your cluster.
Quarkus uses build-time steps for most of what would be done at runtime (DI, mapping, routing etc.) in Spring. This makes it faster to start up and reduces reflection overhead even when not using GraalVM.
It's true, they're similar. Quarkus leans a bit more towards Java EE, Micronaut a bit more towards Spring. I don't think it would be worth switching from one to the other.
Cool, thank you! I've never seen Quarkus before so it's new to me, but I've had some success with Micronaut so I was a little confused. Surprised they don't work together; the goals do seem very similar.
Not quite; AOT-compiled, your app won't need the JIT infrastructure, less memory needed for class metadata, etc. In addition, Quarkus pulls many things to build time, which classic frameworks do at runtime, e.g. processing XML metadata descriptors. This means again less classes need to be loaded (or even present) at runtime, as e.g. the XML parser classes won't be part of the native image at all. Also see the numbers on quarkus.io, e.g. 28 MB vs. 145 MB RSS for a REST + CRUD app as native binary vs. HotSpot.
Disclaimer: working at Red Hat, contributing to Quarkus a bit.
I can believe that Quarkus uses a lot less memory than Spring!
But not simply using Graal.
JIT infrastructure, class metadata, etc are real, of course, but they are a small fraction of total memory use in every app i have ever worked on. Okay, you get a small saving by using Graal, so my original comment is not quite right. But it's not going to make the difference between an app needing 256 MB and 238 MB.
There are two aspects, as I understand it: Graal's native image and Quarkus's compile-time evaluation of annotations. Each is responsible for different aspects of space and time saving.
The comparable compile-time effort in Spring is being explored in the spring-init project[0] and I believe will be a core feature in Spring Boot 3 / Spring Framework 6, along with Graal support.
Actually it does. Native images use about half as much memory or less. Dynamic linking, reflection and speculative JIT compilation are expensive features, memory wise. But you get it back in runtime performance, where native images are slower.
You're missing the point of GrallVm: Write the compiler in Java, not CPP. That greatly relaxes the curve and cross sectional skillet required to implement this function:
Not fast enough for serverless or commandline apps. Native images also consume much less memory (up to a 1/4 or even 1/5) which can save you a lot of money when using cloud services.
If you have users waiting for cold starts (e.g. AWS Lambda without "provisioned concurrency"), the JVM start-up still is problematic, despite all the great improvements that recently have been made (OpenJDK 15 again got some nice improvements, e.g. related to AppCDS).
I'm discussing this in this post about a Serverless blog search I've built with Quarkus and Lambda: morling.dev/blog/how-i-built-a-serverless-search-for-my-blog/.
Disclaimer: working at Red Hat, contributing to Quarkus a bit.
Many simple apps don’t really need all the optimizations that the JVM offers. The vast majority of applications are probably going to have loads that can be handled just fine by running as native image. On the other hand, memory and CPU cost real dollars, and saving that can have a pretty huge impact on costs.
So the build time complexity may just be ok if I get to save a bunch of money by scaling down the amount of nodes I need for my K8s apps.
In the context of Kubernetes I can see how startup time matters. For instance auto-scaling up the number of replicas in response to load. The other one I can think of is serverless frameworks such as Knative where you might be using a scale-from-zero model where you are spinning up a service on demand.
I just build a container of scala graphql server compiled with graal. It is 70mb in size, probably smaller than some js bundles on modern websites. It is static, meaning I can’t mess up class path or jvm versions while deploying
We recently started building small function based REST endpoints for Lambda in Java using Quarkus.
Spring Boot with JVM was slow to cold boot and its native image generation is still way behind. Quarkus provides like 60% of Spring Boot’s features and ease of doing things with bundled option to generate native image which was a win-win for us.
I’m actually jumping the gun here as none of our apps are in production now but it has been a good experience to work with Quarkus so far.
But one might raise a question whether you need to go through all this pain for Java in Lambda and instead use something faster already - NodeJS or Python or even Go.
I know from my experience that my employer's ecosystem is entirely built around having java applications. We moved to kube and that has eased a bit; however, we're all java developers. I attempted to push the bounds of our "use the best tool for the job" policy and worked in dotnet for awhile and I was hit with a lot of pushback. First off was using spring cloud config and trying to figure out steeltoe for my application, but I powered through it. Then came getting support for a new build process with our build agents and pipelines. Just constant pushback on everything. And then there was the review process. It was hard to get PRs done because no one cared to look over "the dotnet" project. I say all that to say that moving to Go or nodeJs isn't easy because it requires a lot of personnel work to get there, for enterprises at least. They have invested a lot into having Java apps and moving to a new stack requires proving out that the investment for the move will outperform the current investment and then some.
I worked on dotnet for 12 years and still do. It’s my first go to if I have to build a quick project.
But my team is all Java developers and we decided to go with Java and Spring Boot few years back for all our microservices. Now that we are using Lambda a lot, the SpringBoot is long in the tooth when it comes to cold boot times and our path differed on which way to go.
I built few Python + Flask functions which have cold boot time of less than a second when equivalent with Java and SpringBoot would take 8-9s. But team was not comfortable with Python. We still have few functions running in Python which are the most stablest and fastest of functions we are running in prod.
We dabbled with NodeJS + Express which no one in the team liked to work on.
So when it was decided that it was going to be Java, we took alternative frameworks to Spring Boot like Quarkus and Micronaut more seriously and went with Quarkus as that seemed to be the one close enough to Spring Boot in terms of familiarity and features.
Java starts fast, and NodeJS uses the same sorts of techniques as HoSpot does.
What you're doing here is comparing apples (large web frameworks) with oranges (languages). If you used a framework written in the same way as Spring Boot with Python, it'd also be very slow to start up.
> What you're doing here is comparing apples (large web frameworks) with oranges (languages). If you used a framework written in the same way as Spring Boot with Python, it'd also be very slow to start up.
OTOH, there's at least an argument that the structure and features of languages influence the kind of frameworks that people tend to use with them. They are distinct but not necessarily causally-unrelated elements of the community/ecosystem around a language
At first glance, this benchmarks seem way to short to for JIT-compiled JVMs to reach steady state. I suspect the high cpu-usage comes from the jit compiler and decreased cache effectivity. I've seen JVMs needing 20 minutes to reach a steady state under load. But then, they've inlined your log configuration throughout the code, quite impressive, imho.
I THINK the author meant it to show time to first request (startup) and how fast you can handle X requests from start, due to Quarkus being focused on k8s/lambda. I personally prefer the JIT over native compilation.
We recently migrated some code to quarkus. My experience:
The good:
* The quality is there. If they claim it is supported, it works. It gives reasonable error messages, etc..
* The documentation is very good, which makes the onboarding experience nice. Give a java dev the site, and they are up and running on their own in minimal time.
* The support on their zulip chat is also very good. People are both friendly and have deep knowledge. Most questions are answered in an hour.
* The development speed is fast. If you file a bug report, it might appear in the next version a week later
The bad:
* If you have (enterprise) stuff that's not yet supported, you'll suffer. The oracle jdbc database driver cost us graalvm. soap took a lot of time to get working.
* cloud integration is a bit too magic for its own good. Quarkus tries to hide complexity by generating config files, executing openshift and docker commands, etc.. But if anything goes wrong, it is hard to find out what it tried to do and how it failed. The options in application.properties are only half-documented and it is hard to map them to the corresponding options of the underlying tools. Error messages are out of context. I ended up debugging maven and reading the source code.
All in all, I am convinced it is a good tool. It has both an open source feel and enterprise class support, combining best of both world.
Quarkus and micronaut really should merge, they have the same goals but yet they fragment the ecosystem because of NIH syndrome. If they cumulated their human resources spring would get a real strong contender
I am currently using it for a pesonal project and so far it's been great.
Expect from a few quirks here and there with new integrations and the fact that I hate hibernate and there is no other option for persistance, it's great.
Super fast reload, easy to implement, good developer tools.
Not the OP, but I generally prefer JDBI for persistence in Java. Much less random glue/boilerplate vs Hibernate. It doesn't seem to have an official Quarkus integration, but you can just pull it in like any other dependency.
Same, I just write my own SQL and row mappers. It's not a huge deal, and then I actually know what the schema looks like (and why queries are slow ;). Hibernate has way too much magic going on under the covers.
I have loved Dropwizard in the past, which encourages the use of Liquibase. Not right for every project, but it was great when it fit.
This is interesting to me because on the whole I feel like I was doing way more interesting things in Hibernate 15 years ago than I see people doing with ORMs today (batching, dictionaries with entity keys, custom type serializers etc). Linq is lovely of course but I’m intrigued to hear what other ways you feel the industry has moved on in this area.
Upserting, typesafe queries instead of raw strings, disconnecting my domain model from jpa, disconnecting my domain model from validation etc.
It's also really difficult to use an EntityManager outside of a JEE/Spring/framework container. They're not thread safe and you have to manage their lifetimes manually.
Better integration with k8s, mainly through more opinionated libraries (you're less likely to accidentally choose heavyweight thing which tend your service towards monolith), faster startup & faster reloads during development.
The equivalent would be actually Spring GraalVM Native. Not bad either but somehow for me it didn't work, so I started with Quarkus and didn't look back.
My guess it meant build for Kubernetes first, born for Kubernetes, like native Americans. I also take Cloud native to meant the same, build for Cloud first. I could be wrong.
It's basically Spring Boot with first-order support for running in the modern cloud -- so fast boot times, integration/extension with common patterns and technologies.
I actually thought the landing page was informative -- the code snippet and boot-time comparisons should give it away. Not used to seeing this kind of energy from java land but it is refreshing.
I'm still not going to pick java for any project ever again since better options exist IMO but this looks cool.
Java has a reputation for being difficult to work with. But I’ve come to like it for business apps. The IDE support (eg intelliJ) is insanely good. However the build system is terrible and there seems to be a lot of magic compared to the simplicity of eg Golang.
For personal projects I continue to prefer golang. For enterprise apps, I think Java still has a lot of potential.
I agree -- I end up choosing things that larger enterprises wouldn't pick because most of my projects are specs of dust in comparison.
What do you think about the angle of Go having a lot of potential (I honestly think it might replace java for large enterprises in 10-20 years?) because it's built for developer fungibility?
If there's one things enterprises want to do, it's reduce the cost of employing resources, and employees are one resource that gets a lot cheaper when codebases are easier to pop in and out of, and you don't need a Java Spring MVC expert, but rather a golang dev fresh out of a coding bootcamp (or whatever actually good shorter-term switch-to-tech education trends come out in the future).
Well, we're talking in a thread about Quarkus, which uses the Java CDI annotations (specifically jax rs) so no need for enterprises to really deal with that complexity : ).
Golang is used by a lot of startups, it lets you move insanely fast. Larger enterprise don't care as much about speed, but care more (allegedly!) about maintenance so as long as there are a ton of Java devs and consulting firms around, I don't see these enterprises switching over anytime soon. With the coming of Generics in v2, I think the language might start to gain a lot more adoption than it has today.
As someone who has worked extensively with containers but not with Java, what does this do to support Kubernetes? Is this just about making the runtime Docker friendly?
The JRE already is Docker aware and Docker friendly in regards to CPU and memory limits. And since Java 10 (March 2018), you do not need to manually configure anything for it to be that way.
Others already explained it better than I can but here I go: This is simply a new web framework (like Spring or vertx). The exciting thing about it is that it is using GraalVM / AOT magic and starts up very fast. Drawback is it requires custom libraries for stuff like Hibernate.
When both are running on the JVM, there still appears to be a significant performance difference, so it should be interesting to compare after the port...
The url you posted leads to a generator for a maven / gradle project. It essentially gives you a hello world quarkus project, including Dockerfiles, mavens pom.xml, etc. You can quickly select often used dependencies / libraries you want to have included. They are put in the maven / gradle dependency lists of the project you are creating. That makes it faster to start a new application.
Are you confused by the wording extension here? They use it synonymously with dependency / library, in this case, maven/gradle dependencies. They are probably extensions in the sense that those dependencies / libraries are useless without quarkus.
Exactly that. E.g. in case of Hibernate ORM, the corresponding Quarkus extension will take care of having the persistence.xml being parsed at build time, registering entity properties for reflection in native binaries, making sure all needed resources are added to native binaries, etc.
They also curate the right set of matching (transitive) dependencies for each library, you just need to add the Hibernate ORM Quarkus extension, without having to think too much about versioning. Also they integrate different APIs: e.g. when having the Kafka Streams extension and the MicroProfile Metrics one, you'll automatically get metrics for your streaming pipeline.
Disclaimer: Working for Red Hat, contributing to Quarkus a bit (Kafka Streams and Debezium outbox pattern extensions).
If you want a small, fast and one file, cloud native experience with familiarity to modern OOP languages like C++/C#/Java, why don't we start evaluating D?
Because it’s almost impossible to find people who can maintain it or add to code written in it. Job on the other hand has 25 years of being the top language for enterprise development. For something to replace it it Hass to be orders of magnitude better.
Indeed. Considering I am upgrading a dozen or applications from Spring Boot 1.x to 2.x. A thousand line stack trace for wrong file permission is so much fun than lame single line Go errors.
Yes, sometimes they are long, but stack traces are also extremely useful. They show exactly where an error happened, and from where the offending code was called. Something you only notice when you're working in a language that doesn't provide them - single line error messages are often not unique enough.
They are also easily parseable and you can filter them to exclude framework code.
I am sure you lose functionality with native image as well - reflection etc.
[Edit: I get the point about GraalVM itself just not the native image in the context of kubernetes. With GraalVM maybe they want to optimize better, allow various other languages to run on the JVM etc. None of that is Kuberenetes specific - not much of a memory or startup speed benefit unless I am missing something.]