Upgrade Java, Spring, and Jakarta EE with GitHub Copilot
Key Takeaways
Upgrades Java, Spring, and Jakarta EE with GitHub Copilot
Full Transcript
Hello, welcome everyone. My name is Sandra Ingram and I got this app and I have to maintain it upgraded it to a newer version. Let's see what we have here. So in the palm XML, I can see that this is a Oof, Spring Boot Starter 1.5 9 project. It's using Java 8. Okay, fine. Fine, fine, fine. Why don't I open up my favorite IDE, which is here IntelliJ, and then I can use GitHub Copilot. I have two ways of using it. So I do install it via the plugins and then it will appear here or I go into the AI chat and as you can see here, I already installed it from the ACP registry. So here I just selected GitHub Copilot, clicked install and there I have it. Also in the plugins, you can find the GitHub Copilot apponization, which makes it even more easy. So now I can here check this out. Upgrade runtime and frameworks, migrate to Azure. Okay, for best results, use that model. Sounds about just right. So here it wants me to upgrade it to 21 LTS and also create a generate plan. So why don't I copy this one and do it a bit newer, huh? Cuz why not? Upgrade to Java 25 LTS. Um invoking generate upgrade plan. Also use Spring Boot 4.x. Okay, and I might even use a newer model since I do have enough credits also. So I will go with Claude Opus 4.6. Yes, that does sound about right. Okay, so why don't we go ahead and try that out? So, here wants to use Okay, okay, along this session. So, I love the fact that I'm here the co-pilot. So, I always wanted to become a manager. Now, I can finally, right? So, I do have the agents that I'm managing here. So, here's my project and I want to go from the current 1 to 25. Okay, and here also it says it currently has the 1.8. It needs to use 25 in future. I couldn't find it yet in my toolings. Let us see. Okay. Found the tools and now it creates my plan. Here the lock. Can see what found here. So, that's already true. I do have 1.8 installed. And I'm currently on a Windows 11 machine. Great. Oh, there we see more. So, yeah, if you're interested, you can always make sure to to check out the locks or you just wait. Or maybe with the AI, we get some time to play a bit of table soccer again. I really love the fact. So, here's also the progress. So, we have the generate upgrade plan and confirm upgrade plan, set up development environment. This one is still running. Oh, yeah, here's the installation of 25. Oh, yeah. So, the beauty of GitHub Copilot app modernization is that it's not only using AI, but also proven open source tools such as Open Rewrite. So, here you can see that it generates a rewrite file. Okay. Okay, the upgrading is divided into four milestones. So, first we're going to use Java 21 and Maven 3.3. Okay, to then uh Spring Boot 3.3 and to then go further. That That does sound about right. Okay, let's do this. So, here in the progress MD, I can check. Oh, here's also the upgrade again. So, now it's doing uh-huh uh-huh uh-huh. Spring [snorts] Boot 3.3 and Java 21. Upgrade using the agent. Hmm. I'm terminating. That's why I can't see here. And here again is my rewrite file. Yeah. Okay. So, that's It's cool, you know, I can use proven open source toolings without even the necessity of learning how it actually works. I mean, creating a YAML file is very complicated to some of our friends. How about now? Ooh. The minus D parameter handling in PowerShell is causing issues. Potentially, I shouldn't have used PowerShell, huh? But, okay. So, now we have that one. Oh, yeah. That was the issue. Okay, the recipe's got to apply successfully. No errors. And now we're removing the rewrite YAML again cuz it's going to be a hidden secret. What we have used, I mean, obviously, it shouldn't be part of our production code, so that's why we are removing it here again. Okay, continue. So, now it checks what got changed with the open rewrite ones. So, here we see the changes. So, we updated java x servlet to Jakarta. Then also the Spring Boot initializer got got updated and also matching messages get got uh, changed to matching messages get first. And now it needs to build the project again to see if it's still running. Mhm, mhm. Build project. Oh, yeah, here there is CVE checks. So, in the yeah, pre-check, you can also see how how we run this, like Apache common thing and then we also check the tests. So, we see that we do have 96 tests that are passing currently. And now we are upgrading it with the agent. Here you can also see the logs, which is pretty cool. So, everything that my AI agent is doing is not happening at watch, obviously. Okay, so this one is working fine. Mhm. Let's see what else we do have in the progress. So, we upgrade Spring Boot from 1.5.9 release to 3.3.1.3. Aha, those were the changes. Now we are building the project. Interesting. Oh, and now we go from 3.3 to 3.4. Okay, so this is nice down too. As I said, I wanted to have Java 25 and Spring four something and it did identify that it can't do it that fast. So now it's going with multiple milestones. So first it decided to go through to 3.3 and now there's 3.4 and then we do here the upgrading to Java 25. Yes, now let me check if there are any usages of duplicated security manager API or zip error in the code base. Oh, that's cool. So it always checks for CVEs, but also for such known issues. Okay, cool. And now the CVE checks are coming. All four milestones have been completely. So we do have Java 25. Cool. I can't wait to have that done. I mean, the managers hiring me, they thought the upgrading would take like weeks, months, half a year. It would be so cool if we do have Friday evening if I can get that done by the end of today, huh? And then I can finally take the time to do something so much more cool, like a green field green grass project, right? You know what I mean? Okay, so let's keep the changes. Okay, so now it's running all the tests. Should also be able to see that here. One test, yeah. That sounds good. It's also checking for the behavior changes, what I do love a lot. So it checks what the code is for and what are like the features in place and then usually makes sure that those features are still in place after the migration. I mean, it really has to happen, right? I don't want to break anything. So here are like the one test where I can have the locks. That looks good underlying exceptions. Oh, some mosquito checks. Mhm. But, those were most likely fixed. Uh-huh. Uh-huh. Uh-huh. Uh-huh. Uh-huh. And then, oh, here's an error. Good. Eclipse adoption. Mhm. Mhm. Okay, interesting. Can't wait to find out how it got And here it's again with results. Compiled. Validated still running the tests. Sometimes it's making me too nervous. I mean, come on. It's totally checking out what's happening. Yeah, so like here Mockito. Cannot mock this. Okay, so the property overrides aren't taking effect. Spring Boot bomb is still pulling the old byte buddy. Oh, that's why. So, okay. Okay. So, okay. So, now we're checking if it's an issue like compatibility. Maybe Java 25 is still too new that we don't have the byte buddy. Oh, so then am I telling me that I can't even upgrade to such a new version? But, there will also come with the text, right? So, if the manager is asking me, "Hey, why did you choose 21 as the LTS and not 25?" I can come up with a great um Yeah, written down what why is not possible yet to switch to 25. But, we'll stay with 21 then. So, yeah, the locks. Yeah, it's still the byte buddy exception. Mhm. Mhm. So, let's see what AI will come up. Cloud Opus, please fix the issues for me. Or if it's not possible yet, please tell me why. Oh, it would be so cool if it would go, you know, and and get up and then create the issue and then fix it even. But obviously, I don't want it to be that strong. I mean, there should be always some human in the loop checking out if there is already the GitHub issue in place and then does it for me. I also upgrade Mockito to the latest available version and Byte Buddy, which are the latest in Spring Boot 3.5 ecosystem. Okay, and now it builds it again. And let's see, maybe it's just a version compatibility issue. And also on the others, it just need to see the progress MD5. Fix test one file changed, five insertions, three deletions. Mhm. [clears throat] Mhm. Mhm. Okay. Byte Buddy experimented true. Okay, that sounds about right. Now it's building the project again, running the Maven clean test compile. Okay. Let's see what happens. Oh, now it's also validating CVs. That's always very important. Let's stay security first. And whenever that we do a change, we should make sure that we at least don't introduce any new security issues. But since we're already touching the code, obviously, we want to make sure that there are no security issues in place. So that's why we run the CVE checks to make sure that it is all upgraded to the newest versions and fixed all security vulnerabilities. Okay, so and again, since we changed a few things to fix all the existing CVEs, we now need to do another code validation. So we check that there are no new features in place, but also all the old features are still running correctly. Here you can see how it does that. Trying to understand what the code actually does. Oh, done validating code behavior changes. That sounds about right. So let's see what's next. One test Okay, so now we're running the tests again. Oh, that's where it's going to be interesting. Great progress. Down to just one test failure. The passes group's two service tests expects Mhm, something. Oh, that that That sounds good. Let's see. Okay, okay, okay. Wait, more cover. See the program. In the passes group's two service tests, mock request get header is member of returns null because the stub is not set. Oh, no. Uh, header is not any string no longer matches null in Mockito 5.x. Okay, so that's a behavior change from the older Mockito version. So we need to use any instead. Okay, so let's uh remove unused any string. Okay, sounds good. Fixing the test, we run the CVE check again. Obviously always when we do a code change, we always need to check that the CVEs are still not in place and that there's all good. Okay, so now I changed the test again and do the upgrade. I'm opening the project to now just 16 minutes by. I mean, come on, how great is that? Can't wait to see this one being successful. So, how is the progress? Oh, do we have a guest? Indeed. Oh, yeah, now the tests are running again since we changed them. Oh, still failing. What? Ah. >> [sighs] >> Isn't being triggered. Returns null is a member of. Uh-huh. Uh-huh. Uh-huh. Messages controller unit tests. Let's see where we have that one. So, we have tests and then there's controller and then there should be this one. Okay. See if that does what it should do. Mhm. Okay. This is distinction. Okay, use nullable string class. Okay. Mhm. All right, as long as it's not null if I said something, then it should be fine. So, now it's running the tests all again. Very cool. Here's my input and that should also be on all that's the plan. Here's the progress. So, here we can again see how the CVE got validated, code, and there we have the test fixed test errors there. Oh, wow. Is member of header parser doesn't stop. Okay. So, now tries to fix and solve the issue by itself. At some point, it might say that can't do it, so then I would be the human in the loop again. But, for now, I will let it try it out. It really feels like I would have my own people that I'm managing here, but just in this case it's the agent doing all the hard work for me, where I have my both hands free to cuddle my cat. Does sound about right for migrating and all those boring maintenance tasks, but somebody has to do, right? And especially with the security CVs in place, totally need to have that upgraded and maintained to don't have any very very bad issues in our production systems when we don't have uh upgraded services in place. I do understand you, right? From the from the point of of like management, if you have to like put in weeks, months, or even years to upgrade all the services, I do understand why they haven't done it, even though it causes security vulnerabilities. But, now with AI, we're still within 20 minutes. Let's see how we can get that fixed. Here, I do have to install a new Java version, but you know, as I'm like super lazy and I want to have my people uh my agent doing all the work for me, I would just uh wait until it gets it. So, it pretty much says the Java home fire is not defined correctly. So, maybe I should have it and say please define So, I don't stop tell it to do the Java home thing better and then I can continue. Yeah, the current Java home is pointing to Java 24. That's it. Okay. I'll check if it is available. Okay. So, let me update the plan. Okay. Done validating behavior changes. Okay. Ooh, that looks so good. Upgrade project to use 25. Whoop whoop whoop whoop whoop whoop. Upgrade using the agent, build the project, 100% compiled validation and fixing. Build project, no CVs, and here are the tests. Oh, there are still a few warnings. See what it does. Yeah, terminally duplicated methods. Okay. Current Java 25 is pretty new. Whoop whoop. So, claims it did it all. >> [gasps] >> Wow. Okay. Okay, very, very cool. So, it did four milestones. We have it upgraded from Java 8 to 25. In the end, it did the step with 21 in the middle and then 25. And here it says I need to restart my IDE to take effect. So, why don't we give it a try and check what's still running. Okay, so this one says it cannot run it because it cannot find the Okay. Uh start the app for me in IntelliJ. Okay, so let's see if it does that for me. So, I really want to make sure that everything is still running. So, I also want to test it like manually, right? Hi. So, okay, so now I can start it. Okay, in the terminal. Um Why would it be in the background? I want to see what it does, right? So, maybe I do it here. Go, go, go, go, go, go, go. Yes. You're allowed. You may access my network. Very cool. And there is my app. A Spring Boot 3353 application. Very, very, very cool. Very cool. All right, I would have done the same. Not really in the background. So, so cool. Great. Oh, yeah. And now it's it knows that I have it run twice, obviously. But but that's All right. So, it's the our port 8080. So, why don't I give it a try? Open it. Local host, it says, 8080. Ooh, it's up. It's up. There you go. All right. You know, the app is not doing much, but but yeah, what I want to say, wow, this is just so, so cool. It did the upgrade for me. It comes out with a very cool plan, so I can even like see what what are the results and how many also CVE things were done. So, now we still have the 96 tests that are all still passing. We we switched the dependencies from like 1.5 something so 2.3.5.3. Java 25, so I can make use of all the cooler Java features such as being more reliable, even more fastly, uh consumes less energy, less resources. So good. Just so good. And also all the potential issues that happened fixed. Very, very cool. And here are a few behavior changes, but not really resulting into any uh changes of my application. We've done this with GitHub Copilot mod in IntelliJ. It's also available in VS Code or GitHub CodeSpaces. Give it a try. Migrate and modernize your application today. Have a lot of fun.
Original Description
What if upgrading a legacy Java app from Java 8 to Java 25 took 20 minutes instead of weeks? In this episode, watch as GitHub Copilot's app modernization extension automatically generates an upgrade plan, applies changes in milestones using OpenRewrite, runs tests, validates CVEs, and checks for behavior changes — all while you supervise.
In this episode, you'll learn:
→ How to use the GitHub Copilot app modernization extension in IntelliJ to upgrade Java runtime and frameworks
→ How the tool breaks major version jumps into safe, incremental milestones (Java 8 → 21 → 25, Spring Boot 1.5 → 3.3 → 3.4 → 3.5)
→ How AI agents use proven open-source tools like OpenRewrite under the hood
→ How automatic CVE scanning and behavior validation catch issues after every change
→ How the agent iterates on test failures — fixing Mockito compatibility changes, dependency issues, and more
→ What happens when a target version isn't fully supported yet (and how the tool explains why)
📺 This is Episode 2 of the Modernize Java Apps with AI series — a 9-part, hands-on guide to upgrading legacy Java applications using GitHub Copilot.
🔗 Series playlist: https://www.youtube.com/playlist?list=PLlrxD0HtieHhaBJWlcxGd-kTDikSD4xyD
🔗 GitHub Copilot Modernization extension: https://aka.ms/GHCPMod-Java
👤 Presented by Sandra Ahlgrimm, Java & AI Advocate, Microsoft
Java #GitHubCopilot #JavaUpgrade #SpringBoot #JakartaEE #OpenRewrite #CVE #JavaModernization #AI #LegacyCode
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
More on: AI Pair Programming
View skill →Related Reads
📰
📰
📰
📰
AI Coding Tools and the Missing Blueprint Step
Dev.to AI
Your AI coding agent starts every session like it just met you
Dev.to · Ohad Krispin
The AI read langchainrb cold. Sense still cut the cost 22%.
Medium · AI
How Datadog Used Claude and Cursor for Test-Driven Production Migration
InfoQ AI/ML
🎓
Tutor Explanation
DeepCamp AI