 We can start. Okay. Thank you very much. Okay. So, okay, welcome to this presentation. Bienvenidos. Good morning. Good afternoon. Good night. For me it's 10, 20 in the night. So today I'm going to present you what has been my experience migrating a Spring Boot application into Quarkus. So I've been hearing a lot about Quarkus and I've been using a lot Spring Boot. So I was impressed and I decided to try it. So this is the main purpose of this presentation, just showing you my experience of following this path. Well, these are the steps that I'm going to follow in this presentation. So just check it out and then you will know when you want to step out. I hope not and I hope to impress you a little bit or at least to light the curiosity of Quarkus and the migration if you don't still have it and I will be more than happy if I can achieve that. Okay. So first I'm going to show you, well, why and who is going to give you this presentation to put you a bit in context and what can you expect from this presentation? So just to probably to lower your expectations if you are expecting, I don't know, a super technical talk or a magistral lecture of Quarkus and then I will explain a bit what it is Quarkus for those that still doesn't know and then it's the, well, for me, the interesting part for me because it's where I've been working the most, I will explain you why I decided to migrate and why I decided to follow this path and invest all these hours migrating one application into Quarkus. Obviously, I will show you which are the steps that I followed in the migration but take into consideration that you can always go to my GitHub repository and you will see all the comments that I followed in order to migrate but I will explain them. Then I will give you a performance comparative but you have to take this as it is. Something shallow, something quick, easy without going into deep details or probably without using the proper tools to do it. It's a simple comparative using the same way to get the metric but probably it can be done better and it can make more deeply metrics about the performance. In the end, I will give you some references that it can help you if you are, well, going to migrate or if you are curious about Quarkus and this migration path. Let's start. I'm one of the organizers in the Barcelona Java user group in this beautiful Mediterranean city of Barcelona and also I'm co-founder of the JBCNConf. It's a Java conference that we host every year here in Barcelona. Next year it's going to be the sixth edition and we gather around 800 attendees and well, Red Hat is always present there and a lot of speakers are coming from Red Hat and other big companies also. If you don't have anything better to do in July, summer near the beach, good food and good weather and good company, then just come to this conference. Also, I work as a software engineer at Red Hat in the application modernization and migration team. We work in applications that are helping people to migrate their applications from different sources to different targets. Here in the left you have, well, the ways to contact me, my Twitter handle, my email, also my blog where you can find a blog post about this migration, also a blog post about using test containers in order to test like if you were in production. I encourage you to take a look and other posts that I'm posting regularly with things that we do in our team and here you have, well, my GitHub account also to see the code. By the way, I'm the guy in the left that is receiving beautiful painting. So, what can you expect of this talk? Well, it's my opinion, it's not a magistral lecture so I'm not going to teach you anything. This is something that works but probably you can find better ways to do it and if you find it, please tell me because I will be more than glad than improve the code. And this is not the way so you can find several ways of doing this and I encourage you to try your own but this is only showing my experience and with successes and with errors and probably you can improve it a bit or a lot but it's my experience. So, what I've done is to use these two versions from Spring Boot, it's 225 and Quarkus is 170. Okay, so brief description about Quarkus. I expect that everyone knows which is this game. So, for those that do not know, which is what's Quarkus. Okay, well this is like the description they can find everywhere. Well, it's mainly Kubernetes native so it's focused on being executed on Kubernetes and interacts very well with it. It also can, you can use different flavors so you can use Java, Scala and Kotlin. And one of the key things is that it's created, always thinking and that it can be easily compiled natively with Graal VM. Also, you can run it using Hotspot on the JVM but I think you will find the best performance if you go to native. And also, one of the most important things, at least for me, is that it's using standard libraries that we've been using for quite a long time. So, it's not redefining anything, it's not making you to move to your standard libraries to the Quarkus ones. So, probably you can find changes on the libraries but it's mostly the standard one. Well, the key point that I want you to take on this is it's really fast, it has a smaller footprint. It's focused on easy to code so it's not complicating the way to use it and I can say it is that way because for me it was very easy. Also, it's super important, it's open source and it has fast-paced releases. So, they are releasing a new version, well, every two weeks, three weeks, it's a very fast cadence and well, fixing issues or creating new extensions or new improvements have to say that this presentation has suffered some changes just because when I was delivering it, some things that were not ready that were already released. So, the team behind Quarkus is amazing and it also comes with lots of extensions. So, at the moment of creating the presentation, there were more than 90 extensions and growing and growing. So, you can find, well, most of the libraries that we've been using are there. So, I don't know, Kiklo, Camel, Kafka, Rest Easy, Flyway, Hibernate, Infinispan, obviously it can connect with OpenShift, with Spring, with, well, there are Kubernetes, there are tons of those extensions that are natively compilable. So, you can always go to native with your code. About the Quarkus evolution, well, I would say that the 001 was released more or less in December 2019 and now we are in the version 1.7 and there's more or less two years and we've come from 001 to 1.7, but it's not because they are doing, let's say, big releases every now and then, but because they are adding minor releases every, well, in this case, in this chart, it was around two weeks. So, it's, there are a lot of changes, really. Regarding the performance, well, I would not enter into number details, but I would like to give you the knowledge about the difference between a traditional cloud native stack and Quarkus native with Graal VM. So, this is a big difference. Also, if you go to a hotspot, you will find a lot of difference. So, it depends on the application, you can find more or less difference, but this is like an order of magnitude. So, you can find that more or less Quarkus can go to half of the traditional cloud stack and it can be 10 times less if you go to native using Graal. So, it's very fast and it consumes way less memory. I will show you later in a comparative. This is, well, the main page of the GitHub repository, just only to show you that there are, in this moment that I captured this screen, it was, well, 100 closed issues, 100 new issues. So, it's in only one month. So, they are doing a lot of stuff. There is a lot of people behind. At that moment, it was 52 people contributing. And there are, well, almost 4,000 people giving a start to this project. So, it's very new, but it's very broad, let's say, with a lot of people trying to use it. So, about the migration. So, now we have an idea of what is Quarkus and we have an application using a Spring Boot. So, let's go to the migration step. I expect that everyone also knows which is this game. I love this game. So, why I decided to migrate from Spring Boot to Quarkus? Well, my experience is that with Spring, it's been always easy to develop and, well, easy to create applications with CDI, REST, different libraries. But it had long startup times. Tests are eternal. Probably, we can improve the way we did the tests. But it was, well, it was a lot of time doing those tests. Because for each one, the context needed to go up. And in the context, there are lots of things being started. So, well, that was the result. It was long startup times. The application was very heavy. So, it was the size of the package was very big. And also, I always had this impression that too many things happen behind. So, if you check the log, you will see different things going on that you didn't expect to happen. Probably, this is because, well, some parts of Spring are needing that. But this can also impact the performance of the startup. So, Quarkus, I read about it and, well, the posts were saying it's easy to develop applications. Okay, I like it. It's fast. Okay. I also like it. It's lightweight. Well, it's not so important, but I like it too. And finally, it's also got IBM compatible. So, I can create a native application that it will allow me to convert my applications into services. And those services, I can use them in the serverless. So, if we go to Lambda in AWS or any other fast, we can just simply have our application as a function that will be only paying the time that it is running. So, at the moment, a lot of those functions are created using Node.js or Python, just because those are way faster than traditional Java. But if I can put my application natively compiled using GrowLBM as a function, then probably I will have a lot of savings in public cloud bills. So, I love this also, because in other companies that I've been, I always heard that the bill for AWS was having big numbers, very big numbers. And I always thought, okay, if there's a way to reduce dramatically that, companies will be able to invest that money in other parts. So, well, I was curious about specifically this part. So, about the project that I'm going to migrate, well, it's the Spring Pet Clinic REST application that uses these different modules. So, we have Spring Data, we have a Spring Web with REST, Spring Security, documentation for the API, actuators, Spring Micrometer, CDI, AOP and Cache. For the Spring Data, this application comes with three different flavors. So, one is JPA, the other one is JDBC directly, and the other one is Spring Data JPA. So, what I've done just for time purposes is just simply reduced to migrate what I think is the most common use case that it is the JPA version. So, on the Quarkus side, well, we will have, for the Spring Data, we will have a Hibernate Panache. For Spring Web, we will have JAXRS, Spring Security, Quarkus Security, Spring Documentation, Open API, actuators, Small Right Health, Micrometer, Micro-Profile Metrics, CDI, CDI spec, the standard one, Spring AOP, we don't have AOP. Spring Cache, Quarkus Cache with Caffeine, this is the library. So, which are the elements that I haven't migrated? As I said, well, I didn't migrate the other two flavors for the persistence. And also, well, in this case, the Spring JDBC querying, so I didn't do this. You can, if you use the library, Agroal, but simply for time purposes, I didn't do it. And also, the JMX parts, I didn't do it because, in theory, JMX is not supported by Graal VM. So, here, I will explain which are the steps for the migration. Let's talk about CDI. In this case, it's only a matter of, if you are still using the Spring AutoWire annotation, it's a matter of replacing it with inject, the standard one. And the declaration of the beans is using another annotation called application scoped instead of bean or any other. Basically, it has auto injection on constructors, similar to Spring, and it's lazy by default. So, this is a very good thing to have in mind. So, the pros with the CDI migration, well, it's been easy. I didn't miss any feature, so it was fine. But in the Spring version, as I said, there are three flavors of the persistence, let's say. And the application will use one or another, depending on the profile we pass on the command line. We didn't have this on Quarkus at that time, but you can always do it manually. So, you can have a config property that you will pass the value on the command line, and then you are going to say which is the implementation class, depending on the value on that profile that you pass. You can see the code on the right. But there was nothing implemented by default on Quarkus. Also, it cannot be a private member on the injection, so at least they have to be packaged with JPA repositories. Okay, so it's about implementing Panache repository. And you will find the usual methods for connecting to the database. In this case, I went to Panache repository base just because Panache repository considers that the identity class is long, but the Spring version had an integer. So, I needed to go and define which is the identity class, but it was easy. So, it's a matter of creating this class, implementing this interface, and that's it. You will find the usual methods, least, find, persist, delete, and others. So, it's been easy. But we don't have query DSL methods, so we cannot have an interface or a class defining those famous methods from Spring that are find by name and age greater than 30, for instance, that SQL query is defined by the name of the method. But you can do similar thing, adding an annotation to a method with the query that you are going to execute. I prefer this way because the other way, the Spring way, you always hit a point where it's super complicated to add the real query that you want in that method. Just because you cannot put parentheses, there are several things that will create a super long name method. And I prefer the query that it's more clear, at least for me. With REST, we have been moved from Spring REST to JacksRS. And in this case, it's more or less the same. It's about replacing one annotation with another. And in a particular case that request mapping that can contain several elements, you need to break it down into different annotations. But it's a matter of replacing strings, and that's it. It's been very, very easy. Nothing to mention here. It was fine, and also Spring can also support JacksRS. So, if you already were using JacksRS, fine, nothing to change. Regarding security, well, we are moving from REST security to Quarkus security. More or less is the same from the user perspective. And you can see here the difference in the code in one, so in the Spring one, it's preauthorized. In the Quarkus one is roles allowed. The only difference that I found, and I didn't know how to do it the same way with Quarkus, is that in Spring, you can use, let's say, more complex expressions. So, in the Quarkus part, it's simply a list of roles that allow it to enter the method, to execute the method. But in the Spring one, you can, as you can see, you are saying, okay, it has a role, and in this case, owner-admin, so it's completely the same thing. But you could be using more complex expressions. I didn't know the way to do the same on Quarkus, simply just passing a list. That was the difference for me that I found. In this case also, this application was using the security, was persisted in a database. So, for Quarkus, we need to use Elytron. And it's a matter of adding this dependency and configuring the properties in the properties file, that it is basically just simply defining which is the query to execute to get the password and a role for a given user. And you can configure several other things, and that's it. Security will be persisted in the database, and that's it. It's basically the same, no code involved in this case. As I said, the only drawback is simply that Quarkus didn't have an expression language for the security in order to check the role that can enter the method. With the cross origin, it's been very easy. Just simply adding two properties in the properties file, and that's it. It will activate, enable, well, if you, obviously if you use true, it will enable the cross origin for your application, and that's it. The only drawback that I found is that at least in the spring version, you can specify the course at the controller level. So, I'm not exactly sure which could be the use case to define different course for different controllers, but it can be done. And in the Quarkus version, at least I didn't know how to do it. So, in the properties, it was at a global level. That's the difference, too. Regarding the metrics, it's about adding this more right metrics extension, and then we can annotate all the methods that we want to have the metrics, and with, well, the regular and standard annotations counted or timed, and then we will have the count and the total time for the course to that method. And, yeah, you can see in these examples, the way that it's going to be shown when you request that endpoint to see the metrics associated to the application. With the metrics, the only drawback is that it had a different naming than with micrometer. So, with Quarkus, that it is using the micro profile, it is using a prefix for some of the metrics, and in the micrometer one, it was not being used. At the time of the migration, they were working on a compatibility toggle to, say, to Quarkus use the micrometer notation, but also they have developed a micrometer extension. So, some things have evolved. As I said, it's hard to cope with their work in order to update the presentation, but also there was a difference between the metrics that you could get. It was not 100% the same, and the biggest, for me, problem was that with Spring, you can use AOP, and then it's very easy to have metrics for lots of methods with only two lines, let's say. As we don't have AOP in Quarkus, well, we need to annotate every method, or we can use inspectors in CDI, or we can use the special hibernate metrics property in order to get the hibernate metrics to be put on the log file. Regarding the validation, so in this case, it's about moving from Spring validation to hibernate validation, and moving from controller advice to an exception mapper. So it's, well, both are using the valid annotation and the annotations for each portion to consider which attribute is valid or not. The difference is with the way that the exception is consumed or treated, and in this case, well, as you can see, you need to create a controller advice class with an exception handler, and then you specify which is the exception that you are treating. With Jack's RIS exception mapper, you are simply implementing exception mapper and specifying which is the exception class. Well, there's not a lot of difference between both of them, so it was very, very, very easy to implement. Nothing to say here in validation. With the API documentation, well, it's a matter of adding the open API extension and in order to specify the global information about your API, you need to simply add this open API definition annotation to a class that extends application, and then you will have it. That's it. It's easy. And you will have, out of the box, you will have Swagger UI. If you are in the test profile, you can enable it for Prod if you want. The only thing that I found different is that in Spring, you can specify which are the packages to be scanned in order to add the information into the Swagger documentation, but I didn't find a way to do the same with Quarkus, so everything was added to the API documentation. Simply, I didn't find a way to do it configuring the packages. For metrics, as I said before, the application was using AOP, and it's very easy to create these metrics. So you simply create an aspect, just specify the expression for an around, and you define a method. In this case, you can see that every method of a class that is a subclass of repository or implement repository will be executed this invoke, and then it will measure the time procedure because it is measuring start and stop. So with five lines, you can have metrics for a lot of methods. We don't have that with Quarkus. So, or you annotate every method, as you can see here on the right, or in this case, this AOP was used for database metrics, so we can do it using this property. So if you add this property to the properties file, then you will get all the metrics for the persistence. As you can see on the right, different metrics for the use of the database in the application. So with one line, we solved the problem that the application was using AOP in this use case. So there are other use cases for AOP, but in the case of this project, this was solved with this line. As I said, there's no expression language to define methods affected, and you need to annotate all methods or to use the property. For the rest, it was very easy. Regarding the local catching, well, it's very similar. So Spring uses a concurrent hash map, and Caffeine uses concurrent linked hash map, but it's adding the extension and then replacing the annotation. I think that for Spring is catch, and for Quarkus is catch result, just specify which is the catch. And then in the properties, you can set different properties for each of those catch. In this case, well, the initial capacity, the maximum size, and others. So it was very easy to migrate the local catching. In the testing part, well, with the Spring, it is using mock MBC. In Quarkus, we needed to go to REST assure. I have to say that I prefer the taxonomy of REST assure. For me, it's more clear, but, well, it's a matter of taste. Everyone has different views on this. So we needed to modify the code to go to REST assure. The only thing that changes is, well, the way to verify the content of the JSON in the response, well, the default way in REST assure is gpath. And with Spring, we were using JSON path. Well, it's very similar, but that's all. And with Spring, we can have tests for roles in the methods. So it's like testing that if a role executes a method, then if it's executed or not, I didn't find a way to do this in Quarkus. So for Quarkus, I needed to create a user that belongs to a role, and then we can test that. But we cannot pass directly a role to a test in order to test the security. Or at least I didn't find a way to do it. About the resources, well, on testing, we are not going to use the real database. We could use it because we could use test containers. But that's another story, and I encourage you to check my other blog posts about test containers because it's an amazing library that can allow you to test like if you were in production. But if you want to go to this other approach, then you need to start an H2 database. Well, using this Quarkus test resource H2 database, the resource class, it will start an H2 database. And then, well, with the configuration on the properties in the test profile, everything will work against this database. With mocks, it's easy. It's a matter of adding the Quarkus JUnit5 moquito, and then you add the inject mock, and that's it. You will have the mock in your test class. So we have reached a point when I tell you, forget everything what I said. That's too hard. A lot of work to do, probably not worth it. There are better ways to do it. So let's explore the Spring API in Quarkus. So if you have your application using a Spring web, just simply use a Spring web extension. And it's likely you will not have to change anything because Quarkus is using those interfaces, and it will do its magic in order to convert to the thing that it really is interested on. So you simply leave your classes, your controllers, as they are. And if you are not using a coordinate case, not covered by the extension, you don't need to change anything. Just leave your class as it is. Simply change the dependency. With the dependency injection, exactly the same. So use the extension and don't change anything if you don't need to. So you always need to check which are the cases not covered by the extension. But if you are not using them, simply use the extension and don't change anything. With a Spring Data JPA, well, it's exactly the same. And in this case, we can use this find by name order by joint methods. You don't have to touch anything in your repositories from a Spring. If you don't use, in this case, invocations of methods from query by example executor or query DSL, if you don't call those methods, then you're fine to go. Don't change anything. Then simply change the extension. With the Spring Security, exactly the same. And also in this case, we can use expressions in the security. Something that we couldn't use in the Quarkus version. Now with the Spring extension, we can use it. So it's awesome. Don't touch anything and you will be fine. And we've reached the point where I show you this shallow performance comparative that you have to take, let's say, very carefully. Okay. So I did the migration on the Spring Pet Clinic and REST application. So the original version with a Spring Boot 225 takes 4.3 seconds to be built and it generates a jar, a uber jar of 48 megabytes. With Quarkus, it takes three times the time and more or less the same size. If you use GralBM, well, it takes even more time. And it generates a package double the size. That's because there are several things that the Spring Boot will do on runtime that Quarkus needs to do on compilation time. And with GralBM, it also needs to compile even more in order to go natively. So that's why these times and sizes. But in fact, we are not very interested or concerned about the size. But we are very interested on the boot time because if we want to go to function as a service, or if we have several services that are going to be started and stopped, and well, it's crucial this time. So with the Spring Boot, the application took around seven seconds. With Quarkus Hotspot, it took a bit more than two seconds and a half. So it's almost three times faster. But with Quarkus GralBM, it took less than half a second. So that's a big difference. We are coming from around seven seconds to less than half a second. And we are consuming from more than 600 megabytes in memory in the Spring Boot version on JVM. We go to 250 in JVM, but with Quarkus. So it's less than two times the memory. And but if we go to native with Gral, we are going to go to 21 megabytes. So we are these numbers of less than half a second and 20 megabytes. Now you can think about having your services as lambdas or functions in the serverless world, because, well, those numbers are allowing you to do that. And also if you are going to have several services starting, stopping, this first time that it takes to start obviously is going to impact in your build and also in the performance of the whole infrastructure. So this is it about the migration and all that I had to explain. But now I want to share with you some references that can help you on going deeper in this Quarkus stuff. Here you have the links to the original Spring Pet Clinic application and the fork on the Quarkus branch that it is the migration to Quarkus. On the right, you have the link to the Quarkus web page, the Twitter handle, the developersredhat.com website where you will find several tutorials and courses about Quarkus and the mailing list where the team and the community around Quarkus will help on, well, on any doubt that you have and also they will receive your feature request if you have some. These are the interactive tutorials about Quarkus. I I totally encourage you to go there and try if you haven't tried Quarkus yet because it's very easy to use environment. You don't mess with your local laptop and everything is ready to work and to and optimized and it will work on the cloud. And it's very interactive and easy and you will you will learn a lot. There are several things you can try. Hibernate, Prometheus, streaming with Kafka, the spring extensions and so on. So I totally encourage that you check that. Also, one of the resources that it's very interesting is the cheat sheet by my colleague Alex Soto that is publishing this document every time a new version comes out and then and there you will find all the new features and the changes summarized and very easily to to consume. The regular page to start an application, code.Quarkus.io, you select the dependencies and it will create a zip file with all the code to start very quickly an application. And now I would also like to introduce this tool is one of the tools that we are working in in the team that I work for. It's called MTA or in the upstream version is called windup and this application helps customers, helps people to analyze applications considering different migration paths. There are several, as I said, you can migrate from camel2 to camel3, you can also migrate from WebSphere to EAP, you can form monolith to cloud and there's also one migration path that it is a spring boot to quarkus and there are several rules covering different elements of a spring boot and it will give you information on your application that will help you to migrate. So these are the different screens. There is one where you will see the different issues that the application will find in your application. You can find them by category, mandatory optional, potential, well. And one thing that is important is that you can see that there are story points per incident. So this will give you also a measure to know if the migration is big, regular or small. So this is also important in order to prioritize different applications to be migrated. And it will give you all the incidents and the documentation related to them that will help you in order to migrate. So here you will find that replace the micrometer code with micro profile metrics code in the files that it founds and the documentation that will help you to migrate on the right. If you hit the file, then you will see exactly which is the line that it is causing this issue to be created. It gives you also information about the different libraries used by your application. And it also has plugins for Eclipse Chain VS Code that will directly in your code will analyze the application and will give you the issues. And then you can apply quick fixes directly to the code. Also, these are a few real use cases of companies that have migrated. And I would especially focus on the Vodafone one that they replaced the Spring Boot with Quarkus. And well, they had metrics about 50% more lightweight in the JVM mode. So those are not even metrics going to native. So going to hotspot, they even found the migration very worth it. And that's it. I will finish my presentation showing something that is not related with Quarkus, not related with technology. It's about sharing with you six different books that I've read that I love them all. And I will also want to share with you. This is because I had a teacher once that finished all the classes recommending books, different books. And I love that action. So these are two on the left novels. The last cartoon for me is 10 times better than the Da Vinci code. It's on the same way. The C Cathedral is a history novel about Santa Maria del Mar here in Barcelona. About knowing how your mind works. Drive is a very interesting book about motivation. And thinking fast and slow will give you a bit of idea about the rational part and the irrational part of your brain. And about sci-fi, I would recommend the Futurological Congress. It's a sci-fi, I'm very funny history about simulated reality. And Ubik, this is one of the most amazing books ever written, about also simulated reality by the biggest, the big Philip Kadik that I love it. I love him a lot for all those books. And that's it. This is all that I had. If you have questions, well, I am here now. But if you prefer to make them offline, you can do it at my Twitter handle, my email. Even you can post comments on my articles in my blog post. Also, you can find those articles in this zone. And last thing is my GitHub repository link that you can go there and check the code of the presentation. And that's it. If you have questions, I will be more than glad to answer them. Thank you. Thank you, Jonathan, for great presentations. I found all the resources very useful. I will certainly go through them. So we are running sort of time out over here. So we have created a breakout room and we can discuss about all the questions that we have in that break. I'm posting the link in the chat so that all the attendees that have any questions, they can go to the breakout room and ask the questions to you. So in the X4 sections on the left side, there is a breakout room with the name Pixies. You can go over there and ask the questions to you. And again, thank you so much for your wonderful presentations. Thank you very much to all of you. Otherwise, yeah, thank you.