Java Modules in Practice with Spring Boot

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Good Video. IMO using module is correct way, but migrating big spring based application is pain in the arse.

👍︎︎ 3 👤︎︎ u/cf1117 📅︎︎ Sep 20 2019 🗫︎ replies
Captions
thank you all first of all for being here and it's really awesome you're all here and right after the keynote so firstly let me introduce myself my name is Jeff coments I live and work in the Netherlands I work for a group nine and I'm a Java developer Software Architect I've been doing java ever since 2002 professionally since 2006 and outside work I'm a husband I'm a father to two girls and I'm a bored bored plane guy I love playing board games with friends colleagues but enough about me let's jump to the modules before we start diving into the subject let's have a brief look at where we are with modules today so first of all to support is pretty good my fans supported modules from the very beginning all IDs have proper support for modules I've been told that Gradle works very well with modules as well I didn't know it from personal experience but from that perspective we can work with modules today and we had that possibility for for the past two years it's been two years since they were introduced already so for that part it's good but then we come to another important ingredient of our day-to-day developer life and it's frameworks and libraries and the adoption of modules amongst frameworks and libraries common open-source libraries is still rather low there's some libraries that are fully modular but that's very sparse amount and the some that took some actions to be compatible with modules but most are not there don't even have roadmap or don't even care then about us developers adoption amongst us that's really very low just from personal experience I've been doing this tour before and I did a project on modules which I will come back to later a little more than a year ago so I had a lot of conversations about modules with other developers and I haven't met one outside that project that really put it into action already so of course I don't know all developers but my personal experience is and if the adoption is very low and then the question is what is holding us back and for that I got a nice analogy from some mark happy to see him here in the room today it said well modules are like eating your veggies you know it's good for you but well is it fun so I did a little experiment at home these are my kids and as you can see they're not rather happy but contrary to what you might think it's not because there's veggies on the plate it's because there's too little veggies on the plate because they're like me a little odd but I like my veggies I like my modules and now you might think why why do you like modules and for that I want to take you back a little bit in time a little less a little more than a year ago I started at a new client and that client had a big legacy application million lines of codes 10 teams working on it's 10 years of legacy and on the first day they handed me a nice architecture overview what's something like this not exactly of course but it was structured not my favorite type of architecture they sort of had some legacy within the legacy that was separated out there was a legacy framework nicely separated out in the picture of course first day learns that reality was more like this more modules involved and more dependencies especially and that's to be expected when you enter such a big legacy project but the surprise for me came after a while of working on this this product more and more I can't realize that there were more dependencies than this there were runtime dependencies mostly through reflection and they weren't nice they were creating cyclic dependencies amongst the modules there are actually reflective goals from the persistence layer back to the controller layer or to the service layer and that made it very hard to maintain and it was very unstructured this was actually the first and only project in my career so far whether I just stopped doing a simple refractory after a week of trying to get it done I just dropped it it was plain impossible and luckily we got a blank sheet for a next step because the client was rolling out a new platform and our team was lucky enough to be the first team to develop an application for the platform so it was kuba needs-based the only thing we inherited was a small proof-of-concept spring boots application based on Java 8 and I realized that there was a little bit of an issue with maintaining structure and maintaining the architecture within this organization and I thought well okay we're here we had some room to experiments let's see if we can pull it up pull it off to make a modular application out for this and migrate it to Java 11 and go from there so what I'm going to show you today is loosely based on what I did for this clients but of course I can't use the real use case so I'm doing something that's closer to me I'll create an application around board games so it's really simple application you can enter some data of a board game there's a REST API you can request it and I also want to have writings for board games good but because I'm currently your only user it's not that exciting so I decided to get my ratings from BoardGameGeek for those who are not into board games board game week is the biggest website on board games and it has information about every board game in the world and it also happens to expose an XML API so that's useful for me so this is the architecture that I'm after this is actually the module graph so at the very bottom you see the domain module which has no external dependencies just the main classes then there are three modules that are more boundary modules so there's a processors module with spring data there's the rest API module with spring MVC and there's the BoardGameGeek client which uses gxb and open fine and of course I want my application to be secure so I have a security module it's using a spring security and JWT for JWT tokens and to tie it all together there's the application module that's spring boot application hence the title of my talk unfortunately this wasn't exactly what I ended up with because originally the project idea was with spring data JPA and db2 database but I thought well db2 on a conference that's not too good of a story so let's use let's make make it a little more exciting but as it turns out spring day demongo quite heavily relies on the classic manga clients which has a split package issue which is a no-go for modules so I had to drop that so sorry for that it's back to spring data JPA it's now post quest which brings me to what are actually the challenges that we will face when migrating this application well first of all as already mentioned there are split packages the split package is a package with the same name being exposed by different modules you might say okay that's not too big of a problem probably I won't run into that but just imagine your favorite beer framework or library that splits across multiple jars mostly they share the same common base package so as soon as there's classes and interfaces in that base package you will run into trouble so this is very likely scenario and the next one it's even more of a challenge our automatic modules so a little refresher for those who forgot or haven't heard automatic modules an automatic module is jar for classic jar file being interpreted by the JVM as a module and it uses some rules for that so first of all it exports and opens all its packages and second of all it reads all other modules and up until here this is not too big of an issue this is just the behavior we all always had so nothing unexpected here the challenge is actually in a module name the module name of an automatic module by default is derived from it the file name and again you might say oh that will not too big of an issue well there's some stuff straight off from the file name and and to illustrate the size of the problem robots halter from Apache maven foundation did a little research for himself and he found 3500 possible collisions in maven central now the top one was parent which obviously isn't too big of an issue but the runner-up is library and that sounds like something I want to have in my application as a dependency so luckily there's a little bit of a workaround you can include an automatic module name in the minimus manifest file of your jar so that makes it possible to reserve a module name for later when you really start adopting modules and that makes it possible to create a unique module name where you see in generals that people opt to use a reverse DNS like we do with packages and with maven group IDs so enough of the theory let's get started what did I do to migrate my application well first of all upgrade your dependencies of course there's security there support issues that might lead you to upgrade your dependencies but as I said the adoption is still rather low but it it is progressing over time so by upgrading all your dependencies to the latest versions you might just resolve a problem that you would have with an older version so next step run your application with JDK 11 or higher again this is a step to reduce the size of the eventual problem and in this case Jack B was removed from JDK in 11 so I had to find himself an external dependency to fill in for that then step 3 compile with JDK 11 or higher again reducing the size of the problem you will probably not run into too much issues in this step I didn't run into any but it's good to do that before you move on with modules and this is an important one and and this is also a deviation from what I actually did in practice at first so first prepare your module structure if your application is not yet structured as modules this is a good time to start making that structure visible so for instance make separate mega modules out of them and the project that I did we didn't do this we started out and we we had one big well not too big but it was one application one maven module we said whoa let's make that a module first and then we'll figure out the rest later and split it up later on but by that we took on all the problems with migration at once which brings me to step 5 step 5 is start adding module descriptors bottom up so start at the very bottom of your mojo graph and that's what I want to show you but because yeah this is really representing the experience I had when doing this so we see here is the structure of the application as application module the BoardGameGeek lines domain persistence REST API security just like you saw in the picture and at the bottom of the module graph domain so let's start there so new module descriptor and I want my module name to be unique so I do reverse DNS and it's not really exciting modules so there are some classes in there in two packages and as these are being used throughout my application it makes sense to export both these packages so there we go we have our first module now let's see if we can make this work let's see if it builds oops first problem already so scrolling up here you see a lot of stuff let's see if we so it says here something about forking surefire took me a little while but apparently there's back in a surefire incrimination with modules and j-unit jupiter luckily there's a milestone version of a surefire that resolves the issue so let's go fix that so yes in Portuguese and I just run it again okay cool so it's building now so let's see if we can also run it Oh already running sorry okay starting oh that looks good so now let's give you a little tour of the application it's really simple first of all I need to login to get a token let's see it's working I've got my token then the database is empty because I thought JPA to rebuild it at every start so I will now post a new game to the database and response got a new game cool as you see here there's the BoardGameGeek ID which I use to get the ratings through a separate endpoint so if and I'll try to do this this is actually going through boardgamegeek and to prove that this is correct I have the corresponding page here open well okay maybe if I reload this now okay there's a little bit of a running issue but you see I'm more accurate good so we have one module that's really nice now let's hop on to the next so a new module descriptor I won't bore you with doing all that I prepared myself a little descriptor here okay to antastic there so what you see here again module name and it requires the domain module because the domain classes are in the API of this module then it requires java xml bind that checks being it requires rancor range XB and it exports only one package that's a factory package and we're at the factory classes that creates the instances that are in other packages that i don't want to expose actually but Jax B requires some access to do deep reflection on the XML API so I have to open this XML API package project B so let's see if now still works and immediately we run into neutral okay so there's a module not found that's too bad and there's a whole range of DS it says the online module reads package comes an XML bind from both exp imple and exp core so apparently there's a split package issue in the current reading version of Jack B this too has been resolved but it is only a build version that's available and that has to do with the whole Jakarta EE migration so there's no official version of exp 2.4 yet but there's there's a built version available in maven central and it's fairly stable so I'm using that let's see here I can replace all this with just this now run it again and again so there we go it started let's briefly prove that it all still works so I have to log in and create myself a board game and then this was the the module for the book game V client so let's see if this job works and it does so we're good there now there's of course more modules so let's continue resistance create a new module descriptor and here you see it again requires the domain module it requires Java persistence its JPI and requires spring data JP a spring transaction for metro sections and then it's exports I think it's only package yeah it's only package and also it opens the package for deep reflection and what you see here I didn't do that in the previous module I specifically say here okay I want to open it to hibernate and to sprinkle meaning that autumn modules are not allowed to use the reflection on my module so it gives me a little bit of control of who can excise access my my stuff ok let's move on where are we wrists so this is a really simple one requires the domain module it only requires spring web as an external dependency and then it exports it's only it's only packaged okay let's move on security so here you see this already has a lot more in dependencies but mostly it's spring and what you might also notice is as I said before most libraries choose reverse DNS Spring doesn't do that but Spring has an automatic module name in all this jars so it's really really good that they did that and I think spring is one of the few that has the right to say okay we're just spring there's no competition for that and then it also requires sorry jjw T and X for some reason I also ran into a embedded Tomcat that was required here I didn't dig into the details I just found out it required that so I added it then it's exports it's both of its packages so the core of the security module and the rest API that's belonging to that so you just have to believe me here it it still runs I won't bother you with proving it because I want to I want to proceed you might say you miss one module and that's true but the application module is a separate step and I will I will try to explain why because up until now I've been cheating a little I have module descriptors everywhere and maven and IntelliJ say okay you're using module descriptors we're acting like these are modules but I'm not really running on a module path yet so the next step will be adding a module descriptor to my main jar which will make sure that we actually run on a module path which will cause us to run into new trouble that we didn't run into yet because now we will run into the reflection issues so expect a little bit of a bumpy ride it's just one module descriptor but it will take a lot more effort good there we go application this is a little bit different than the others of course as you see here it requires most of the other modules then there's a Java instrument for bytecode instrumentation their spring boots spring boot other configure spring beans spring context then it exports both packages the one has the application class and the other has the Java spring configuration and it also opens both of the these packages to spring for spring core does require a deep reflection on that so let's see what we get now oh no first I forget I want to show you this so now if I open my spring configuration clause it starts complaining this is okay I need Java persistence here for the entity manager because right here I'm building up my entity manager and injecting it in my beans and there's some domain classes and now I could resolve that by adding these directly to my module descriptor but that's not exactly what what I think is right here because it requires java and javac spur systems because it depends on my persistence module and the same goes for the domain module that's there just because my other modules require that so I can solve that in a different manner so let's go to my persistence sorry yeah don't give it away so what I could say here is requires transitive which says ok every module that requires my persistence module also requires my domain module and the same goes for Java persistence so this in my opinion is is more correct the domain module is required because it's part of my public API of this module and the persistence Java persistence module is required because this this module depends on it so now everyone run it hopefully we'll get some output but that's not too much output so it immediately bumps into an issue with a JWT so let me scroll to write and it says here JJ WT Jackson contains this package and JJ WT API also exports that and that's a split package issue now this one I tried to resolve to you file a PIR to the library and help the library maintain your odds and he appeared very open to the idea but there were some limitations in both this time and other agenda are for instance support for Android with Java 7 background so there's there's no progress there yet but good news is is just two classes causing these issues I have a little patch prepared so this just adds these two classes and get rid of one of the dependencies I won't bother you with the details so it solves that so just an example of what you can run into by just depending on an a library so hopefully this time we get a better result we see the spring banner that's good but that's about it let's see what it says right here it says illegal access exception module boardgame security does not open ball game security to module spring core okay I forgot something so that's actually great output I get there so even better like a more or less copy paste that so it was the security module so I need to just a little bit and I know the same applies to that package so I'll also add that so next chance okay different error which is great so we're a step further here I have to dig a little bit more and here's the course it says plus not found exception so apparently there's something that depends on java scroll okay I didn't spot that so again here let's add that to manuscripts then no that should be better and hopefully this time it will start to bad okay okay this is actually one I really skipped over so it also requires bye buddy now the fun thing about bipod is that's really modular but it's still compared with Java it I won't go into the details but it uses a nice library to generate a module descriptor for a Java IDE and when I click on this I will get their module description so that's really neat I think just wanted to show you and show that briefly so hopefully startup errors are over now oh no there's one more no such method exception and where you see here there's a dynamic proxy issue with spring for one of the Constructors of one of my classes and as it turns out yeah you see here of Genesis that's a library that allows you to construct classes without calling the constructor so there's all dirty stuff going on down in Spring Framework and it gives me a lot of value but it's not really neat but there's a solution for that as well and this is actually a module name that I really like jdk unsupported this really screams you're doing something wrong here but we allow you to do it but it's a deliberate choice so let's see if we now finally get it to start already there we have it but that's your starting key application so let's see if it still works first of all login okay that's good that got myself a token and then do a post for a new board game that shouldn't be too exciting instead it's HTTP 415 and supported media type what did I do that's not something I expected and I actually got this in my project and I thought well what's going on here and it misled me a little or it misled me big-time because I thought wow 4:59 must have changed something else there's something wrong with my codes and it really cost me two days and then I realized that the answer was right in front of me because when we look here at the logs there's a warning here so blah blah blah blah all that writes it says that's not open the command package to ejection data bytes okay I could have seen that earlier but as you see sometimes you get a little bit of unexpected outcomes and that will lead you astray so luckily I now have the solution so let's see it's domain oh sorry notes and again I can more or less copy-paste that need to adjust a little and the module system really gets me proper output it's just that spring doesn't deal with it the way I would hope it does so let's rerun that that's good now let's quickly go through this problem resolved luckily and now for the final test does it still go oh no this is actually something oh I know what I did wrong sorry um my bet remember that I commented something else so that's that's the the new check speed depends India that I added later was a little too quick with adding that and I forgot it so I owe you some proof that it works so let's run through it again login create a board game and I'll get the writing yes we're there it's all done our application is modular so that's cool but at the same time while I was on that project I was also very interested with in Colleen and I thought can I do both can I get both modules and Colleen and as it turns out you can colin has module support since 1.3 and the way they did it is not exactly what you might initially expect but it turns out to be really neat because they say okay the modules description the module info the Java it's good as it is so if you're doing modules with Courtland you will have one Java phone that your module info the Java so they they kept the same thing which also has a nice side effect because if you want to do mixed source like I'm about to do now Java and Kotlin in the same project here for my job description so let's see if we can pull that off I have five minutes I'm hopeful so to prove you that this works I will take the class that's at the core of almost everything here and migrator to Kotlin oops that's not what I yes so IntelliJ is helping me out here oh yeah so there's a little bit of stuff that I won't need because it misunderstood my intentions from the Java code so I now have nice Gatlin class and it's okay : that's not configured well then configure it for me Java with maven yeah the main module right now you see it opens the problem because it did some stuff over here now unfortunately this isn't correct because this is configuration for Kotlin only and not for mixtures but I'm prepared for that so this is a correct configuration and all another thing I want to show you is that it also did a little modification here in my module description it says now requires call in standard lip and I said in the beginning there's no external dependencies now you might think okay there's an external dependency popping in but in the end you also implicitly depend on Java base and this is just the culinary equivalent for them so let's go and run this takes a little more time because it has to compile the Courtland stuff for the first time but it starts and again to prove that it still works I can actually stop there here because it's already touched the boardgame class but I will go on and see ever get the writing so everything still works so I myself thought that was really neat so to wrap up I learned a couple of lessons from doing this first of all go bottom-up start at the very bottom of your module graph because that allows you to do this step by step and not take all the problems in one go you can even spread it across sprints or iterations the way you want in that way second of all test all the paths of your application on every step as you saw during the demo especially in step 6 when we actually start running on the on the module path there's so many things that you can run into at runtime that you would not expect so properly test everything you do during this process and then remember the logs have the answer the module system actually produces proper outputs and throws proper exceptions with messages that you can almost copy pasted into your module description so your first gut feeling should be look they're like the HTTP for 15 I got it it would would have saved me two days of my of my time if I would would have just looked at the logs first and then finally it still involves quite some pioneering it's not really mature to use for all purposes so consider for yourself is it worth the effort for me in this case in this project for me it was definitely worth the effort but that doesn't really mean that it it's worth the effort in every next project I will start so to make the consideration yourself I'm wrapping up and with that we've come at the end you can find the code of my demo on github and if you have any questions remarks please find me on Twitter find me an email find me in the hallway after the session I really appreciate all your feedback so also please give feedback through the app or in person preferably thank you [Applause]
Info
Channel: Oracle Developers
Views: 9,704
Rating: 4.9183674 out of 5
Keywords: groundbreakers, oracle cloud, oracle developers
Id: u4VV9NSK_0Y
Channel Id: undefined
Length: 45min 17sec (2717 seconds)
Published: Wed Sep 18 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.