 Hello, friends. Welcome to another Tech Talk. Today, we have the opportunity to talk with a person who has a very unique skill set. He's a Quarkus expert and also a Spring expert. So I'd like to invite you to the stage. Eric, welcome, Eric. Hey, thanks, Edson. It's good to be here. Yeah. I can see that, yes, we have this very interesting subject today, Quarkus for Spring Developers, and it seems that you've wrote something about it, didn't you? Yeah, yeah, I did. I spent pretty much this entire year since January writing this book that we recently published, taking a look at Quarkus from the, looking at it through the lens of someone who's familiar with Spring and the Spring concepts and conventions and whatnot, and comparing and contrasting with Quarkus. Cool. Well, we can't wait to hear more about it. So we'd like to say that today, live from New Hampshire and caring North Carolina, welcome to Dev Nation. Awesome. Thank you. It's great to be here and I'll apologize up front for my kind of gerry-rigged background here. I couldn't figure out how to get a nice virtual background that didn't make me look like I didn't have any ears. So apologies. It is what it is at this point. So people were probably more interested in looking at the big thing on the screen rather than this little box here on the side, right? So like Edson said, when I first started, a little bit about my background, before joining Red Hat, I have a huge amount of experience in Spring. I worked for a lot of financial services companies where that standardized on Spring. And it kind of unique for me is I skipped the whole Java EE thing. I went right from thick client desktop using Swing with maybe a little bit of servlet-based back end to Spring. And I skipped Java EE and all that kind of stuff. So for me, when Corkis first came out, it was like, okay, how do I learn this? And like anything that anybody's familiar with in regard, not just with technology, but when you're starting to learn something new, you're always comparing it or contrasting it with something you're familiar with, whether it's technology or cooking or whatever it is that you're doing, you're always looking at it through the lens of something you're familiar with. And when I was starting with Corkis, everything that I learned and everything I did, you know, when I picked up Jack's RS and JPA and all that, you know, the micro profile stuff, it was how does that fit into things that I know? How is it better? How does it make my life easier? But at the end of the day, it's how does it compare with things that I know? And so we decided to actually write a book about it because when you start looking at Corkis, there's tons of guides out there and the guides are really, really good. But the guides really focus kind of on one thing, like building a restful service or using Hibernate or Panache or whatever. And sometimes it's a little bit different than what a spring developer might be familiar with. So we wanted to kind of level set and take a look at, well, people who are familiar with some of these concepts, the conventions, the auto configuration, all that kind of stuff, how does that work? And what does that look like in Corkis? And what does Corkis do similar and what does Corkis do different? And so we tried to do it through code examples by looking at, why did we decide to do Corkis in the first place, right? What was the problem that Corkis was trying to solve that's out there? We didn't just decide or not, I keep saying we, I wasn't part of the Corkis team, but they didn't just decide, hey, we need a new Java framework out there just because that there's a reason for it. So why? And then once you kind of get some foundation and for me, I kind of like history a little bit. So some of the historical aspects of what was going on, what were the challenges and why this, we needed this kind of thing. So after that, we took a look at how do you get started? You know, I'm familiar, if I'm a spring developer, I'm familiar with the initializer, I'm familiar with all of the starters and whatnot and what they do. What does that look like in Corkis? How do I actually get started building something? And then from there, we take it into, okay, rest is pretty common out there. You know, there's a lot of restful applications. So looking at like spring MVC, spring web flocks and how does that translate into something in Corkis? And then extending that, we use this kind of the same example that we started building at the beginning and each chapter kind of adds onto it and we added persistent. So looking at both, you know, spring data JPA and Corkis has this thing called Panache that is kind of like an abstract or not kind of it. It is an abstraction on top of JPA just like spring data JPA is. And so you'll find some of the patterns are very, very similar, excuse me. And then looking at event-driven services. So things like in-memory trend, in-memory data buses or Kafka events, you know, producers, consumers, K-native, you know, how would I deploy my services into something like K-native? And then once you have your application, how do you operate it? You know, what does it look like? What are the tools available? And when you start looking at containers, Kubernetes, you know, deploying or running on the cloud, what are some of the differences or challenges with either one? And we tried to show that through example. And I have to give some credit as well to Daniel Oh and Charles Mulyard. They helped co-author some of these chapters. So chapter five, the event-driven chapter was authored by Daniel Oh and chapter six by Charles Mulyard. They were fantastic to work with and very, very good. And we actually got somebody from Microsoft to write the forward. So Martin Verberg wrote the forward. And what was kind of interesting, something that he said in the forward, which kind of struck with me. I'll make this a little bit bigger so folks can see. What he kind of said is, you know, it's kind of that time in your career. If you are a spring developer, you know, I know for me personally, when Corkus first came out, it was like, why would I want to do this? You know, I'm familiar, I'm good, you know, I've got my head down, I'm good with what I've got. But it's kind of like, well, there's kind of this new way of doing things, you know, this build time optimization thing. It's kind of one of those points in your career where even if you don't adopt it, you should at least, you know, stick your head up out of the weeds and kind of take a scan about what's going on out there in the industry and explore something new in depth. And the book, I feel, makes it easy to do that. And, you know, obviously Martin feels the same way, otherwise he wouldn't have written it. So I don't want to spend a huge amount of time, you know, looking through the book and the chapters, and then I want to dive into some code. But as you can see, it's pretty, it's pretty in-depth about, you know, some of the concepts, you know. And one thing I try to focus on, me personally, I'm a very big fan of test-driven development. And so, you know, I write tests for pretty much everything. You know, there's folks out there who might say, oh, there's a, you know, there's some limit that you can reach where, you know, you're putting more effort into writing a test than the benefit you're getting. And I agree with that, but you need to have a good test suite, right? And a lot of the, you know, whether you're spring, corpus, whatever, a lot of the things that you find out there on the internet or Stack Overflow or whatever are, you know, how do you solve a problem? But then how do I test what I built? And so, within each chapter, you know, we'll spend half the chapter talking about how to build something. And then the second half of the chapter is, okay, now that you build that thing, how do you test that thing? So we focus a lot on testing. See here, so all the examples, you know, there's a whole set of example code that's out there. There's a GitHub repo and I'm gonna, you know, drop into my IDE in a second here, but there's a whole GitHub repo. It's organized by chapter. So, you know, for example, we're gonna look at some of the persistent stuff today. So the chapter's organized, you know, there's a bunch of different examples and when I built the examples, I tried to follow a pattern that they're, to keep both the corpus and the spring examples as similar as possible. So to keep the code, and that was kind of one of the focuses on this, was to keep the examples as close as possible. Even that might be a better way to do something, but from an understanding perspective, I want the examples to be as close and implementation as possible. And throughout chapter four, that's pretty much the case. But once you start getting into like the event driven stuff and the cloud stuff that tends in any of, I don't know if you can see my hands, but it tends to branch off and diverge quite a bit from an implementation perspective, but at least they all implement the same use case. So that's helpful. So even in the event driven scenario, we implement the exact same use case, but the implementation is quite different just because the technology is different under the covers. As far as versioning, the, you know, it was just like a writing a book, you know, with technology the day it's published, it's out of date. So, you know, once you print something in these days, so keeping up was tricky. The book, the examples in the book were published, I think with Corkus 2.1.4. So it was published at the end of August. Just recently yesterday, Corkus 2.3 came out. So all the examples are up to date with the latest versions of everything. And I'm gonna keep doing that as long as I don't have to make code changes that would involve, you know, kind of republishing the book kind of thing. But the Spring examples in the book are 2.5.4, I think, and it's been updated, the repo to 2.5.5. So the repo is current with whatever the latest versions are at this point in time. And I'm also trying to make note, so in the main read me, you know, I kind of mentioned the versions as well, but then, you know, as new things come out that I didn't necessarily implement in the examples because it would have made me change the text. But I did kind of comment on, you know, what might have, as new things have come out, what I might have done differently in the examples. And if we do a new, you know, a V2 of the book or a re-release, you know, in a few months, we may incorporate some of the stuff into it. But I didn't want to change the code in the repo so that it, I want to keep it so that it matches what's actually in the book. Because I think that would be super confusing to folks. All right, do we have any questions? It's in on the text. Otherwise I'm going to drop into the IDE, not yet. Oh, question so far. So please go ahead with the code. All right, so let's see it. So I've got an IDE, I've got my IDE here, I've got the examples re-boiled it up. What I'm going to look at today is I'm going to go into chapter four and I'm going to look at, you know, one of the more common things is, you know, I need to build a REST layer and I need to talk to a database. It's a pretty, pretty common, you know, architecture right now. And just, so what I'm going to do is show a spring data JPA example alongside what Corkus calls Panache, which is its abstraction that sits on top of JPA and Hibernate. Under the covers, both use, you know, Hibernate is the most common ORM tool or ORM engine out there in the community. So they both sit on top of Hibernate as the JPA abstraction. And as you'll start to see, and I've got some code, and I'll explain the code in a second, that's, it's pretty, pretty similar. So if you're familiar with spring, you know, picking up Corkus or, you know, I like to say Corkus is based on a, on a breadth of standards. So like Jacks, RS, JPA, whatnot, there's not a lot of Corkus to get in your way. And most of the Corkus stuff happens at build time is where the Corkus magic happens. So on the left here, and I'm just going to minimize that part just to give me some more screen real estate. On the left side, I've got the Corkus. And on the right side, I've got spring data JPA. And as you can see, I can make this a little smaller. You know, most, you know, at any entity class, this is an entity class, all the kind of magic of an entity class is up at the top. I'm not using something like Lumbock, you know, that we can have a whole separate conversation about why not, but I, I'm not using Lumbock. So, you know, under the constructors is a whole bunch of, you know, boilerplate getters and setters, two string hash code equals all that kind of stuff. So you don't need to see that. But as you can see, and even if I open the imports here, these classes, if you were to do a diff on them, they're exactly the same. There is no difference between these two classes. You could copy paste one to the other and it would just work because they are the same class. Those who are familiar with spring data JPA would be familiar with this repository thing. So in spring, you build a repository extending, you know, there's a whole different flavor of base interfaces that you can extend. I chose for whatever reason, this one, the JPA repository, there's a CRUD repository, there's a sorting one, there's a bunch of them. And then I added an additional method to it to find something by name and it returns an optional, whether it was found or not. And on the left side, you've got this corkis or panache class. So the first thing you'll notice is it's a class instead of an interface. So the reason behind that is spring data JPA at runtime, when you start up your application, will scan for all of these interfaces and it'll build dynamic proxy implementations for them. So there's a bunch of different ways you can build them. You can build your own classes and wire them together so that spring data understands where they are, but at the end of the day, spring data is going to build an implementation of the interface and implement all your methods for when it does that at runtime. Whereas with corkis, all the, you know, kind of one of the main benefits of corkis is it optimizes stuff and I'm just, you know, in air quotes here stuff on the JVM. So part of that is well, rather than build an interface, I can actually build a class. And I still have this plethora of base implementations that I can pick from. I just picked, you know, the basic one that kind of looks similar to JPA repository, but it provides a whole bunch of, you know, crud-based methods for me or create, pretty much all the same stuff you'd find in the spring version. And again, I implemented the same find by name, but I actually implemented the method. So you notice I'm, you know, returning, I'm finding something and I'm querying by name and, you know, returning some optional. You know, spring data JPA has a way where I can annotate my methods with like at query, I can do name queries, and I can do all the same stuff with, with Panache. And it's, it looks pretty much exactly the same. You know, my, my use cases here are pretty, pretty simple. And then the only other thing is the annotation. So by default, corkis uses CDI as its dependency injection framework. So because I built an interface, I need to tell the dependency injection container that this is a beam that needs to be inject, injectable within the context. But what's kind of interesting with corkis is all this beam injection stuff happens at build time, not at runtime. So like all the, and maybe to make more sense if I actually go to, you know, where the class is used. So in spring MVC, you build a controller class and in Jax, and in corkis uses Jax RS. So you build resource classes, right? That's just a different naming convention. But all this, you see the, I'm using constructor injection that should probably be familiar to spring folks because I know the spring team themselves recommends constructor injection over like a lot of wired fields when I was committing stuff, you know, a few years ago, if a pull request didn't do it that way, if you did, you know, the other way they would actually deny it and you'd have to go fix it. So they, they certainly prefer constructor injection. There's a whole slew of reasons why I personally feel it's better anyway than field level injection, which, you know, if you want to have me back we can have that conversation too. But in any case, they're exactly the way the beans are injected is done exactly the same. But back to my previous point about build time versus runtime, in corkis, this binding in the byte code for binding a bean injection point, which is done by type just like in spring, it's actually done at build time. So the corkis build process will generate all the byte code and kind of pre-warm the just in time compiler so that when the corkis application starts all that binding and injection, you know there's no proxies or anything. It's just, you know, the real thing is just kind of there. Whereas in spring, all that stuff has kind of done at runtime. But you can see if you're not familiar with Jax RS it's very, very similar. So, you know, you annotate your class with kind of a base path, just kind of like in spring you do a request mapping and then you just implement your methods. So in spring, all the mapping annotations, you know get mapping and put mapping and post mapping and all that kind of stuff has all the metadata as part of the annotation. So like the media types and paths and all that stuff whereas in Jax RS, all those they're all separate annotations. So, you know, you've got to get annotation or produces annotation or path annotation. And what that's kind of interesting if you notice here, you know on the spring side, you know I've got some validation stuff which I have over on the Corkus side as well from the beam validation spec. And then all the imports are, you know the spring, the typical spring MVC imports but on the Corkus side, there's nothing Corkus-E I would say Corkus-E here it's all built on standard. So Jax RS, I'm using, you know standard Jax RS out of the box. Under the covers though Corkus is built on a reactive engine that uses NetE which is the same engine that is under spring web flux. And in this case, in this example this is Tomcat behind it but the fact that Corkus is reactive doesn't mean you have to build your application reactive. Corkus will kind of understand what's going on. So in this case, all my method not doing anything reactive here I'm not using any reactive types I'm using, you know, standard JDBC stuff. Corkus will just kind of figure out that hey, this method needs to be moved off of the IO thread onto a worker thread whereas in the spring example everything is done with the thread per request model. So every request that comes in is on its own thread so the developer doesn't really have to worry about that. So other than that, I mean, you know the implementations, the actual code like in the methods is pretty similar. I mean, you know, spring has this response entity Corkus has a response object you know, if I wanna change the status code on the response or anything like that transactional, you know, doing transactions you know, it's very similar except the spring one uses the spring annotation for transactional whereas the Corkus one uses the JTA transactional annotation. So it's kind of cool if we run this so in Corkus, one thing that I can do you know, I'm gonna use maven here is I have this thing called dev mode now you remember I the only thing I didn't show was configuration in Corkus, I don't think there is any but when I run the Corkus application I can run it in what's called dev mode Corkus sees, hey, I have a Postgres driver here but you didn't configure a data source so what Corkus will do is it'll actually bootstrap a Postgres container for me and it'll bind my application to the container and you'll have to forgive my machine the fans are spinning so fast I feel like the laptop's gonna lift off into outer space So you can see Docker is... I'm running Docker desktop but if I was using Podband it would work just the same you know, the data source is starting it's pulling a database and I actually custom built a database image for this exercise just to kind of pre-populate a schema and pre-load data into it so that all the examples are based off of the exact same schema so there's no change in the schema here and so while that starts up you see this thing called dev services started so it started database and now my application has popped and I can start interacting with it and if I just do like EIE, 8080 Amen, there we go we got some JSON back, right? So that's pretty cool but if we kind of start to compare and contrast what's going on if I go over to the spring one so the first thing I need to do is I need to start a database, right? So I need to... Where was my database? I need to start my database I'm gonna start the image manually and while that goes into the right place and then I'm gonna do... I already built the application so I'm gonna say java-d spring.data source.url and gdbc Postgres localhost 543.2 Fruits and target name of my app here gonna get the name of my... Where's my binary? I don't know why my auto completion isn't working jar There we go So my application starting up still going and it's up, right? So now if I go and I do the same thing and I get it back but what's kind of cool if I wanna actually look at the process so I have a little script that will calculate the residents at sites RSS is the memory footprint of the application not just the heap size but all the off heap stuff as well so if I take a look at that I could see my application is using 434 megs of RSS space So now if I kill my application my database is still up and if I do this kind of the same thing on the corkis one it's up and you notice it started in like four seconds what did the spring one start in? It's going by log 11 seconds so 11 seconds for spring four seconds for corkis now if I do the same HGP request just a foot funnel request through and then look at the RSS that I'm using 184 megs same application, same use case same implementation and I don't know what the percentages are in my head but 434 versus 184 and I started up in a third of the amount of time The other thing I know we're kind of running out of time here but I also do so corkis makes it really easy to do this native image stuff so I could also do I already built the native image I'm just going to find the command here I export the data source and then I run my native image I started in there's my start time 221 milliseconds and if I funnel the same request really back and if I do my RSS 32 megs, 33 megs same application so you can kind of see some of the differences here so I know we have five minutes left Edson do we need to pause for questions we do have some questions actually people are starting to fire the chat right now but let's start with the first so let me get it for you so I was able to type this one like Raja is asking do you recommend giving up Spring for a new product probably talking about corkis what do you think? yeah it's an interesting so it comes back to I mean there's a lot of factors that go into it obviously I think corkis is a good thing especially for you know it's a good thing for Java and I think VMware and Spring have realized this I mean corkis wasn't the first to about the same time corkis came out you know that Mike or not was doing something similar with this build time optimizations stuff so I know like at Spring 1 they announced that Spring 6 which will be kind of the next kind of major release of Spring and then Spring Boot 3 will follow that is targeted for the end of next year but part of their reasoning is that they want to re-architect and refactor the framework because kind of they see that this kind of build time and ahead of time optimization for Java is a good thing and that's where industry is going so I would say you know if you're familiar with Spring as much as I'd love to say yeah give it up and don't do it I don't think that's going to happen Spring is certainly powerful I'm still like it it's a very it not that cork I don't want to say corkis is immature but Spring is a very mature framework it's been around for a really long time but part of you know it's kind of a double-edged sword part of being around for a very long time makes it so that it's going to be really hard for them to re-architect and fit I mean the whole if you understand kind of how Spring works under the covers it's based on a lot of the AOP and dynamic proxying and runtime stuff that when you start looking at this build time you know doing stuff at build time kind of goes contrary to that architecture so and then having to retrofit that without breaking everything and still supporting everything that's already there is it's going to be tough I mean I'm sure they're going to do it and they'll do a good job of it but it's a lot of work it's going to be a lot of work mm-hmm cool yeah now we have a lot of questions just because are you the first one I can go past a half hour if we need to yeah cool let's try to read the first and Asif is asking will you discuss this db custom image and Quarkus integration I don't know if I got the question yeah I mean the custom image I built was just you know I took a Postgres the standard Docker hub sorry that's why you know it's live yeah now you know you're really live when the phone rings the dog barks or something like that so the yeah I lost my translate oh the db image so the all it was was I took the standard postgres 13 image and I added a init script that creates the schema and then a SQL file that inserts data into it just just to make it easy because what I wanted to show and what I didn't show here was you know the having your application create the database for you when it starts up populate the schema what not is is great for local development but what it doesn't test is if you're building a jpa entity class and you've got these different annotations most of the time your app is connecting to a database that already exists and so how do you test what your application if you can actually bind to that schema right and so a better way I feel of doing that and I'll just show in here in YAML is rather than telling Hibernate to generate the schema tell it to actually do a validation so if you're running against a container image that already has a schema let it let your when your tests start up or when your application starts up validate that the annotations that you wrote on your entity class actually generate the proper DDL to match the schema you're trying to connect to and that's what I did for all these examples so that's why I built a custom image just for that cool and let's see Shane is asking how do you suppose like user credentials sessions and other stuff differ between Quark as Spring I'm interested in Quark Quark sizing a spring project but I but didn't know if it's a lot of work or not for this part so what do you think so in sessions are they talking about I assume HTTP sessions so forgetting about the technology choice under the covers you know when you start talking about distributed applications like I'm going to deploy in or instances of the same app you know the whole the HTTP session thing where you're putting something in the session and storing it per session maybe isn't the best way of doing things in a microservices world because in microservices you want some kind of backing service so if I wanted to do that why not just store it in something like in fitness band or Redis or whatever right so to me that would be a better whether you're doing Quark or Spring that's probably a better approach for for microservices that being said like I said the underlying engine for for Quark as is the reactive netty and Quark as sits on top of eclipse vertex so if you're familiar with vertex vertex is a very slim lightweight and high performant reactive framework and so Quark as sits on top of that and so under the covers the reactive engine handles handles a lot of that stuff for you but it's kind of abstracted away from from the developer a little bit I don't think really answers the question but yeah I understand and John is John Klinga is asking why didn't the book cover the Quarks Quark as a spring compatibility APIs I'm going to give them give them hell afterwards so it so the book talks about so there are these spring compatibility APIs where you can take a spring application and you can with minimal invasiveness run I don't want to say run it on Quark as but change it into a Quark as application and we have and I can I can go back to this the browser and show you there's a workshop or a self-paced tutorial that'll take take you about 45 minutes if you're interested in it that you know kind of take Quark as look at this like the spring NBC spring data GPA annotations and whatnot and kind of do it put an adapter layer at build time on top of it so that you don't necessarily have to change your code and those are those are good for for getting started but I don't think the and you know again I'm not part of the Quarkas team so I can't speak for them but I don't think the intent there is to kind of start off and build fresh or new applications that way they're meant for hey I want to get started with it or I've got some applications that don't use a lot of like in-depth spring things so things like if I'm doing like really complicated exception mapping or as an example you're going to run into edge cases really fast so it's good to to kind of play around and learn about Quark but if you're going to start fresh I would I would start fresh and the book has like a a section in chapter two that that kind of says the same thing that I just said but the the focus of the book was looking at spring and looking at Quarkas and kind of kind of merging them together another question here from Oro how do you solve hypermedia any equivalent of hey to s I believe Quarkas does have it I personally haven't played with it but I believe can go out to I mean I can I don't know I can take that offline and look I believe there is an extension for something I can't speak personally to it because I haven't done it okay cool okay this is a cool one Matthew is asking for spring boots it's possible to generate swagger documentation for your API is this as easy for for Quarkas so let's put a caveat there the generation of the swagger stuff isn't part of spring boot right spring doesn't have that you've got to use something like spring dock or what's the other one spring fox this is a few open source projects out there but it's not part of of spring in chapter two or chapter three I actually talk about that and I showed Quarkas does have an extension that's just built into the framework that can do that and you know I could take my resource classes and annotate them or generate open API stuff just and it looks looks the same but but yes oh yeah if you add the open API extension generates it for you and in dev mode you have the swagger UI added for you automatically as well yep and that's super cool and Dominic is asking any spring feature you miss as you have like a Quarkas equivalent for any spring features I miss that there isn't a feature for is that yeah yeah that's a good question I haven't come across anything yet I mean I know what so when I ended and show it in the demo but when you start getting into like reactive or event driven Quarkas it's just kind of built in with like the reactive stuff the the micro profile reactive extensions and the spring I don't want to say the spring version of the spring answer to that is but the the way you would do that in spring is like with spring cloud stream or spring integration and whatnot and one thing I found that actually wasn't there in spring or that maybe I just didn't know how to do it I mean I banged my head against the desk for hours before I just wrote something myself is a way to do a think about a use case where I have an app that's listening to messages from Kafka or you know some kind of message broker doesn't have to be Kafka and that I want to serve those as server send events so listening and then publishing and having to like store the stream and wait for subscribers to subscribe to the stream because you don't want to just buffer those in memory because you can run out of memory real fast if you get a lot of events I could not find anything in spring cloud stream or spring integration to do that I had to kind of drop down to project reactor I has this concept of a sync that that manages subscriptions and whatnot whereas Quarkus it's just which is built into the event bus like Quarkus it's just there it's part of you know vertex it's part of the underlying vertex framework yeah from yeah if I yeah the only thing that I think that Quarkus didn't have like when I needed to talk to two separate databases the first versions of Quarkus you couldn't do that but now I think it solved so for my project at least I can do everything and but one thing that I really miss in spring when I have to touch my spring project is the dev mode so once you touch Quarkus dev mode you're absolutely spoiled and then dev services so like you need a database or a Kafka broker or Redis or a schema registry or HashiCorp Vault or any of these other types of services that you need to run locally you know now you don't need to set up like a dark compose or anything like that Quarkus dev mode will just spin it up for you automatically absolutely yeah let me see lots of questions it is even hard to to read it Alfred is asking what is the future for native images are there any new features coming new features for native images I know and this isn't specific to Quarkus but I know there's the new flight recorder Java Flight Recorder for GrowLVM that was contributed I don't know exactly what version but that's kind of new and that's just like you know across the spectrum for anything using GrowLVM I'm not in the GrowLVM space so I don't really track it as much I just know I do you know maven package-p native it works and then I I get a native image or if I want to do it in a container I can do a container build and make a native image and it's worked for the last two years right so I don't really have anything else to add to that okay and Ja Milton is asking does unit test change when using Quarkus yeah so I I think I ran out of time and I wanted to show this I don't know if you have a second you can go back to my my screen share here my IDE I wanted to to show kind of some of the tests and yes spring has its own testing framework for you know testing different layers of your your application right so testing a resource versus testing like a controller class here it's the pattern is the same so like in this case where I'm doing do I have the right test I know that's the repository here we go so like spring MVC uses this mock MVC thing to do tests or you know you could start it up and do like test for us template or something so spring web flux now you bring if you're if you're doing reactive so kind of the one of the cool things with Quarkus is Quarkus doesn't care if you're doing reactive or not and you don't have to do something special to do reactive or not spring you kind of need to make that decision before you've written a line of code am I doing reactive am I doing blocking because once you make that choice you're kind of stuck with it unless you want to rewrite your application and so that even falls through when you start doing testing so like the way you write your tests in for spring MVC is different than the way you write your tests using a web flux based controller whereas with Quarkus it doesn't really matter that the test is written exactly the same but the the kind of algorithm of how you do testing is the same you know you take your in this case the resource or control layer that has a dependency on your repository layer you stub out or mock the repository layer that way you can test your kind of your resource layer or whatever layer you're trying to test in isolation so you know that the pattern is do your mocking and in this case they both use Makito they both use JUnit5 the mocking is almost exactly the same like I think it is exactly the same what's different is the kind of the expectations in the framework inside so you know with mock MVC you do it this way with with web flux you do it another way but in Quarkus Quarkus uses rest assured for its testing rest full layers you could use rest assured with spring as well I personally never have but you could but even testing like your repository layer now like I want to do like test that the operation that I that custom operation I wrote so I can stub out and I can have in both cases have spring or Quarkus you know run each test in an isolated transaction so that it rolls back the database after the the test has completed but you can see I mean it's very they both use assert J I mean if you love assert J like I do you use it in either so it's very very similar hey Andres is asking what is what is the GraalVM rolling Quarkus and how is it important? Yeah so so this is my personal opinion here I think you know a couple years ago if you were to say the word Kafka it was kind of like this shiny ball that was traveling through space that everybody was trying to to catch to say oh I need to do Kafka I need to do Kafka even if it wasn't the right fit for the use case I think native image in GraalVM is a similar thing right now it's like everybody's got this native image and I'm trying to move my hand to the camera here native image up here on this pedestal and everybody's like trying to oh I need to do native image I need to do native image without thinking about well what are the the good things about it what are the things that you really need to think about before you go down that path and what use cases is it really good for so it's a to answer the question GraalVM is a a virtual machine that's out there that can take your compiled bytecode and actually translate it into a native machine binary like Linux or map or windows or whatever but during that process it does like a tremendous amount of aggressive dead code elimination so not just in your application but if you took if you formed a dependency graph of all the dependencies your application depends on and then you opened up all those jars and you took all those classes out and you threw them in a directory GraalVM would go through all of that and look to see is there a static binding at build time where path can flow from one method in one class to another method in another class and anything that didn't have a path that just threw away and got rid of and once it was done it would form this binary and that's what makes it super small and super fast to start up because there's not a whole lot of in air quotes here stuff that's in it that being said there are drawbacks to that like think about monitoring if you're using agent-based monitoring like you attach an agent to your JVM like a Dynatrace-type thing that's not going to work in native image because there's no JVM right it's just you know like running any other native binary on the machine so you've got to figure out what your what your monitoring story is going to be it's really good for short-living processes so think about serverless like running Lambda functions or Azure functions or what what pick Cloud provider of choice or you know an OpenShift or whatever being able to quickly start these things up have them do some work live for a while and go away but historically like the Java runtime especially the just-in-time compiler is really really good about watching your application over time and optimizing it based on what kind of what's going on on the JVM and you don't get that in Gravian so if your process is like really memory intensive and really long running not saying it won't work but you know the JVM might over time outperform the the native image cool yeah we're already on top of the hour so last question Vinicius is asking how about the exception handling layer with Quarkus do we have a base class similar to the response entity exception handler in Spring to treat the runtime exceptions? Yeah so there's a few different ways to do it me when I've done like exception handling yeah you can always throw those exceptions I actually wrote an article on Dzone a while back about exception handling in general because you know there's always compile time versus runtime you know checked exceptions are good checked exceptions are bad runtime exceptions are good runtime exceptions are bad but we can have that conversation another time if you want but essentially with Spring you can do it a few different ways you can do like exception handlers you can throw you know the I think it's response status exception you know where you can customize the the point Quarkus sitting on top of Jaxrs has all that same stuff so if you look in the Jaxrs spec there are different there's like a generic I think it's web application exception and I'm you know someone can correct me if I'm wrong I I could be in wrong names but there's a a base level exception that's like something bad happened and you can customize the thing but there's also like smaller I don't want to say smaller but like sub exception types for specific use cases that you can throw or you can like I did in my response class you can you know throw a return a response object that has whatever you want which is similar to the response entity class in spring cool well Eric I'd like to thank you for this amazing talk and congratulate you for again one more time for the book because it's a it's a great content and you can tell that the audience was super interested because we had a lot of questions and comments so thank you very much and if you have anything else to present please reach out to me and we can schedule something new for you yeah and if you I don't think you have my twitter handle I'm not a huge tweet person but you know if anybody has questions that didn't get answered and want to reach out through twitter we're not happy to start a conversation there I think it's just at Edie Andrea okay cool yeah well thank you very much and hope to see you soon in our next divination offering bye bye everyone