 This talk is about modules and Java linker. I think pretty much about modules have been covered. I'll take this opportunity to cover it very briefly once again and cover some important points about it. And also the new tool Java linker, it's the de facto standard for creating Java JDK images now. I'll just cover it slightly here. And I'm Bhanu Prakash, a work for Java platform team Orakil. OK, this is the agenda. I'll slightly cover about modules. Again, module dependencies, this is some stuff. And then J-link and packaging. This talk is not about the actual code constructs or something like that, but it's more about the way JDK9 impacts the development environment, be it writing the code, testing, deploying, configuring, all those configurations, actually. All those things this talk is all about. And I will also introduce you to J-link plugins, some of the built-in plugins, and some of them which are shipped with JDK9. I'll also cover them. Yeah, this is a regulatory statement. Don't make any recent decisions based on this. Jigsaw, I think some of the problems we have seen earlier, still JDK8, maybe in special cases, otherwise JDK had been a single monolithic image. And it had been a problem since a long time. I mean, be it embedded devices or cloud-based platforms, the space is very important there. I think in JDK8, it had a tool called JREcreate, but that is for embedded JDK. I'll cover it later. But otherwise, it was single monolithic image. It was a big problem there. And then the class path or jar help. The way any moderate or big applications, they will have a number of jars. And the dependencies among the jars is not properly specified. And it would lead to lots of problems, something like shodding of the classes, or maybe discovery of the classes itself. You may frequently encounter no-class definition found errors, something like that. Some of these problems have been addressed by Maven by using the static number of jars and then versioning and all those things. But still, if you are a normal development environment, you still face all these problems there. And then the performance. Performance side, two aspects, startup and security. JDK being a single image, JDK was either JDK for developers or JRE for runtime. Any moderate application had to be, even in a small application, had to ship the entire JDK to the customers. And then it would lead to problems like how to download the entire image. The JIT doesn't work if the entire image is not there. And also, some other problems like the startup being slow. Maybe that is because the discovery process itself. Even the Java version command right, it requires maybe some 300 classes to load, actually. These are all existing problems. And these are solved. These are some of them are solved using jigsaw. First one is modularization. This is, I would say, a significant and disruptive change in JDK 9, if not phenomenal. I think the users have to say that phenomenal. But it's a disruptive change. Modules has been introduced as first-class citizens. Again, programming construct as classes and packages. Modules have been introduced now. There is a specific dependencies. You can mention what a module is all about. You can package a certain set of packages in a module. And you can mention what the module requires and what it exports, all those stuff. And it solves the problem of class path. I mean, by the way, when you mention lots of jars in a class path, you are really not saying which jar is dependent on the other jar. It's like a mesh, actually. It's all dependencies or a mesh. You cannot see. It's hard to say which jar takes a preference or hard to see. If two jars have same fully qualified class name, then it's again a problem. All these problems. Class path has been replaced with module path and module dependencies and a specific structure to address these problems. And performance and startup. Performance, right? Startup. I mean, I would explain more about startup in the coming slides when I talk about the J-Link plugins. But since JDK now allows to build custom images, right? Some of the things can be pre-computed, something like system module graph. And then those things can be used for decreasing the startup time and also the performance aspects. I mean, you can download the dependencies, incremental downloads is quite possible. Maybe I should use this one. Module is a collection of classes and data. It's again a collection of packages, maybe you can say like that. And modules have an important construct called, I mean, it's called module descriptor. It has visibility rules about the modules. I mean, what a module does? It does some activity and it requires some dependencies and it tries to explore some aspects. Some programming like classes or something like that. OK, this is one important aspect when modules was introduced, accessibility. Accessibility is like, OK. You, with JDK and module site programmer, have an opportunity to hide some of the things or maybe make the changes local to the module and to expose parts which public requires, actually. You can see the statement there. Public no longer means accessible. When you say a class is public, it doesn't mean the class is accessible from outside. It's a simple name application that I used here. Confure app is an application, is a module. It is dependent on another module, Confubor. And it has read functionality on that. It has read dependency on that. It's a read edge. But it is reading only some parts of it. OK, now in summary, when you make a class public, that alone is not enough for your class to be utilized outside. So a class has to be public. And the corresponding module descriptor should specify that as an export package under the export package. And the dependent modules, they should mention that as a require, under the require category. So all these three things should be satisfied to make a class really public. And this VM checks, I mean, this accessibility is made very strict now. I would say right from the compile time and even the runtime, even the VM, even all those, it's imposed everywhere now, these accessibility rules. So even the regular Java reflection, it may not work unless you expose a package. And this is an important change. Why? Because it disallows some of the programming constructs that were available earlier to the programmers. And those they cannot use, programmers may be like something like Suncom internal packages, something like that. But for JDK9, there is a hack that the JDK team has provided, which you can use for now for JDK9 to utilize internal packages. So it's called as ad exports. Any questions around this? I think if there is any key take away, maybe this is the slide. This is a small app. Confu app is dependent on, it's a custom module, another module, Confu board. And the same module is dependent on Java.sql. How their module declarations looks like is like Confu app, you can see that there is an x, requires class here, requires Java.sql. And the Confu board is like an independent module. It just exports the Confu board package there. This is the actual module dependencies. So I have just declared that Confu app requires only two modules. Actual module dependency graph looks like this. All the modules by implicitly dependent on Java.base. And you can see here, Confu app is dependent on Java.sql. But Java.sql is utilizing two more modules there, Java.xml and Java.logging. OK. Then how Confu, the main app, how is it able to use it? That is with the use of exports public. I mean, exports public, maybe I'll cover it later. This is another construct in module.moduleinfo.java file which says that when a module says exports public, the dependent modules get those packages as free, actually. All those modules as free to the users. This is the transitive dependencies. The Confu app is dependent on Java.logging indirectly. It's like a transitive, A depends on B, B depends on C. That is because Java.sql internally utilize using some logger API, which the Confu app doesn't use. This is the immense amount of effort has been went into JDK9 modularization. I mean, the platform itself has to support now. Unlike earlier, maybe with embedded JDK and all, it was a different case, actually. They just provided compact profiles and all. But now with the platform itself has been, he's supporting inherently this feature modules. And you can see the module graph here. I don't know some edges are missing here. But can you make any conclusions on this graph? I mean, anything, any points to note here? There is a edges here. Everything is leading here. I would say that is missing. Any guess, I mean, what does it say? What does the graph say, I mean? There are lots of packages and for all the packages, all the packages are dependent on Java.base. This is required for any basic JDK image. And graph is acyclic. Graph is acyclic. Module graph should not have any cyclics. I mean, it should be acyclic in nature. I mean, there should not be any cycles within the dependencies. That is one conclusion you can make. Any questions till now? Is it clear? Going well? I think this stuff was covered earlier in the earlier sessions, actually, how to compile modules and how to generate modules, basically. It's like normal Java command we use. And it's normal Java program compilation, except that you pass module.info class name, Java file name as part of the Java command. And one additional thing to note here is when you are compiling the main module, you'll have to mention module path here. In the module path, you'll mention the path indicates where the dependent modules can be found, actually. Mods. And there is another way you can compile multiple modules at a stretch in a single shot. It is called as module source path. Using this option, you can compile multiple modules in a single command. And maybe I'll just go through the example I have. This is the small app. Kung Fu app. This is one module. You can see the module.info file here. It requires Kung Fu bar. It's very short, right? Maybe I'll just show you here. I have the same thing in the slide also. OK. When you do, Jmod describe on these modules, right? For example, the standalone module Kung Fu bar. You get this output. This clearly says that this particular module requires certain modules and this exports certain modules, certain packages, basically. And you can see the requires mandated Java.base here. This was not part of the module.info file, but still it came up here. This was actually this gets added up by the bytecode interpreter. I'll just run through that. This is my example. I have modules here. Kung Fu app and Kung Fu bar. My Java version is build nine, JDK9 version nine, build 131. It's like two weeks old build. What I would do is just this is the output. This particular app, this particular module, right? It requires Kung Fu bar module and it requires a mandated Java.base. Though it was not there in the module.info, it came here. It is being inserted during the compilation time. And then it requires Java.sql because the example uses some SQL JDBC statements. And then it conceals the actual package, actual module. I don't export anything outside. There is another option in Java, in the Java command. It has been enhanced to display the module discovery path, actually. It's called minus x diagnostic resolver. When you add this option to the Java command, right? It shows all the way a module discovery happens, actually. Happens. How individual modules are read and the order of the discovery. This is like debugging purposes. Go with linking. Before I jump into jailing, I will just cover a brief history about jcreate, jrecreate, that was added in JDK 8. As I said, Java image had been like monolithic image, either JDK or jre. But JDK 8 had a provision, actually, to create a shrink compact size of JDK images using profiles, actually. Compact profile, compact one profile, compact two profile. Compact one profile was something around 11 MB. Compact two profile was maybe like 23 MB, something like that. And till JDK 7 or maybe JDK 8 also, right? Oracle ships the actual JDK images for the target platforms. Let's say Linux, Mac, all those stuff, all those operating systems. But with JDK 8, especially embedded JDK, it actually shipped the jrecreate tool, which developers can use it to create the actual JDK. This was an attempt by Oracle to string the JDK image size. But the jrecreate tool, which was actually an attempt by Oracle to string the JDK image size, but it would still pick up the jars, some jar selectively. But that doesn't mean that you will get all you require. I mean, it gets you all you require, but you also get something which you don't require. So that support was not there. So J-Link, as part of JEP 282, J-Link was implemented. J-Link started as a small command line utility to generate runtime images for the developers. But soon it became a de facto standard, actually. I mean, even the JDK images generated the binaries, I mean, like the regular JDK images also use this command now on day-to-day basis. And it has lots of options. And actually, this plugin is at a very nice spot, I would say. You might know, actually, Java command is supposed to be dumb. I mean, it generates bytecodes for a given class file. See, it doesn't. It's supposed to not to do any optimization there because it has to adhere to some spec and then it has to generate the bytecode as verbose as possible. But when the application is run actually, then optimizations actually trigger, maybe the GIT compiler or any optimizations for that matter ahead of compilation now. But all those optimizations incur cost, actually. It takes lots of computation power and all. So J-Link, this tool is in a very lucrative space where it provides an opportunity to do some more optimizations just after the compilation. We have all the class files, all the jar files for the related to the application, and before creating an image in that space, actually. So J-Link, as said in the spec, link time is an opportunity to do whole world optimizations that are otherwise difficult to compile and cost later on time. And the best part about this is it exposes API. So developers can write their own plugins. And it also ships, like, 12 built-in plugins. So developers can use them and also extend the existing plugins to improve the functionality. This is the regular JDK image. You would see you'll have been JRE live and within JRE been live, right? This is the regular up to JDK. This has been the image structure, right? But with JDK 9, the image structure is going to be just been gone. There is nothing like JRE. There is no RT.jar. There is no tools.jar. All those things have been removed. It's like plain directory of beenconf and lib. Lib will have the modules there. So J-Link, as shown in the figure, it takes group of modules and packages into your runtime image. That's the actual functionality of J-Link. So command is simple. It takes output as, like, you just need to mention the output file name and add-mods. In the add-mods, you mentioned the root modules name. That's the main module name that you are trying to compile. You are trying to cap package. And the module path, where you will mention the dependent module names. I'll just create it quickly. This is my main module, ConfuApp, and the mods. Mods is, sorry, module path. Module path is where dependent modules can be discovered. This is the path where it searches, basically. This is mods. And then in windows, the modules have to be separated by semicolon. That's it. That's it. It generated a JDK image with my own modules. And there are two modules that I mentioned. I'll just go inside that. This is the simple directory structure, beenconf, lib. It has only essential things here. If you go to lib, the majority of the JDK image size is contributed by modules. And this is like 29 MB now. Modules is the packaged modules, actually. Basically, all the modules are packaged into this file. And this is like 29 MB. If you look at the original JDK9 image, it was something like 153 MB. It has come down to 29 MB. But we can shrink it further. And the best part about this generated image is that all the modules are now known, actually. I mean, the module graph is pre-generated. System module graph is pre-generated. So when I say bin slash Java list mods, it shows me all the packaged modules within this JDK. And then it's also quite simple to run the main program now. I just say Java minus same. That's it. If you remember in the earlier slides, I mentioned that if there are any dependent modules, we need to mention an original option called module path. So you don't need to mention now, actually, because this is a generated image created out of those modules. So you don't have to mention those module path here. You just mention minus same. This is the main program name. That's it. Or maybe this is the app too where I'm using JDBC program here. Yeah, this is some known exception because I haven't written exact. I don't have those drivers and all. But yeah, this is how you invoke. It's quite easy to invoke those Java programs now. You can see here, when I do list mods, it listed all the modules properly in orderly fashion. And then running is quite simple. It's just Java minus same and the main program name here. And no module path is required. Okay, plugins. Plugins work in two phases, actually. While, see, here is an opportunity where you have lots of classes packaged as modules. Plugins provide an opportunity where they work in two places, actually. While going through all those individual modules and you have an opportunity to go through each of those classes and do some optimizations there. And also the second part is, you can add additional information, meta information to the image. Those are the two things. And then you can see JDK itself has some 12 built-in plugins. And you can use any of these or you can also extend. I mean, you can also write your own custom plugins. And another best part is it provides all these things programmatically. You can extend these things programmatically. And all these plugin APIs is experimental. I mean, they are subject to change, but you can still use it. As I said, this is like the workflow. In the left-hand side, top right, you'll see lots of modules there. You say it's like a grinding machine. It goes through all the modules, individual class files. And then you have an opportunity to remove some class files or modify instruments on class files, et cetera. You can all do all those things. Wherever cross-marchs are there, you can write plugins there, actually. And the image creation part, you can add some meta information or you can do additional compression, all those things. In internal study, it was found that this J image was able to string maybe like five times more than the regular jar image, regular jar compression compared to regular jar compression. I'll just show you some of those results also. Optimizing, this is one plugin. Here, we will talk about system module descriptors plugin. Since when generating a JDK image, right, custom image, you know the modules, the program is going to access, though the system module graph is pre-generated. And it is generated using a system module descriptors plugin. Actually, this plugin came out of a need, actually. The need was that after implementing Jigsaw and all, the startup time actually went up. I mean, it increased compared to JDK8. So that was a big problem. So what they found is that significant amount of time was spent in just parsing the module.info files and locating the modules and discovery part, basically. So this plugin was written and this worked out well, actually. It showed some 50% decrease in the time required for startup. And also, yeah, it improved lots of performance, actually. And also, it reduced the memory usage also. You can see this is the sum of the results. This red bar matters, actually. This is the user time where the, when the command started and when the command end, it's like 50% decrease in the, more than 50% decrease in the startup time, I mean. And this plugin was identified an essential plugin. It is enabled by default, actually. If there is a reason for you to disable, then only you can disable it. Otherwise, it's enabled by default. So you can tweak the setting using this option, installed modules option. Okay, this, I cannot show you demo of the system module descriptor plugin because it's all milliseconds. So please excuse me. And the compressed plugin. This is, again, actually, this works in three levels. Level zero is about string sharing plugin. String sharing plugin is, like, see, we all know about jar files, right? It's like nothing but zip files with additional meta-nf file. And that was all the compression that JDK was using till now, actually. But with introduction of Jigsaw and then introduction of plugins, right, it provided an opportunity, a window where we can do some more optimization on those individual class files, actually. So this string sharing plugin, right, actually what it does is, it goes through all the class files in the modules and it extracts the UTF-8 strings and it creates the global string table and differences elsewhere, actually. I mean, like, it's used elsewhere, even including the Java-based module classes. This itself resulted in lots of decrease in the actual image size generated. And with level two, right, with level two, you will include both these plugins, string sharing plugin and zip plugin. Zip plugin is the normal jar plugin, the normal zip formatting. This works on the class as a whole, but it doesn't look into the class data as such. But string sharing plugin, it optimizes the data. So these are the sizes. I mean, if the compression was not there, it was like 28 MB. With level zero, it was like 17 MB. With level two, it came down to like 11.5 MB, actually. Or maybe I can just quickly do that. I'll just regenerate the image with compression on. Take much time. As, yeah, you can see here, it has come down to 13 MB here. Earlier it was like 29 MB, if I remember correctly. It was 29 MB without compression and now it is like 13 MB now. And this is not all. We can add few more command line arguments to J-Link tool, which does further compression, actually. Something like, when I was doing experimentation, like some more additional arguments like strip debug arguments, strip debug statements, include locales, there are some more plugins. I mean, like some more additional options, the size comes down significantly after that. This is another minor, very small plugin. This might be useful when you are delivering JDK image, your own custom JDK image. You want to add your own release information to the JDK image. In the, I'll just show a demo of that. It's quite simple. I just come here. By default, custom, any JDK image has a file, text file called release. It just has information about the OS version, OS version architecture and Java version, all this stuff. And we can add any more information we want here. Maybe quickly, I'll just add some more information here. There is an option to add some information. You can also remove some existing information. Maybe I'll just add some information. Source equal to Eclipse on 2016. Oh, sorry, I used a different image name. That's it. You have a JDK image with all the new information. I just go here and just type, where is the resource? Yeah, you can see here. Source, this has, this got appended to the existing release info file. I would say that along with the other contents, it has added some more extra contents to that. Like this may be useful for any custom runtime images. You may want to add some more additional information about the licenses or maybe build numbers, et cetera. These are some of the plugins. Yeah. In summary, JDK9 is an important change. I mean, it's been described as a significant change. The accessibility checks have been much more made, much more stricter. The accessibility checks are now implemented at the run time, even at the VM level. So there are more restrictions, actually. Now the code can be more secure. It also improves the usability, maintenance, maintenance is also easy for the developers. Simply upgrading to JDK9, it depends actually, migrating to JDK9 from JDK8, like JDK8 projects, right? It depends on how you have written the code. If you are using safe constructs and programming guidelines, requested programming guidelines and things, right? It's not that hard, actually. I mean, like you can do it your own face, except the dependency stuff. You may be using some extra JAR files. So those JAR files also need to be modularized. Either you can do it or you can just wait for those tools to come up with those modules. But it's like, there is an easy way to turn a JAR file into a module. So there are required plugins, I mean, required utilities there. And yeah, some libraries may require changes. And more importantly, JDK9 will also may affect the build processes, actually. The way, the way, build, I mean, like deployment and build things are happening. We're happening, it might affect there because now it's different now. I mean, like the regular class parts may not work. You need to, there's some learning curve in dealing with module parts and all. But yeah, but you will have some rewards also. Yeah, that is all I have. I don't know, I exceeded my time. I'm ready for questions. Have any questions on, in general, I mean modularization or maybe any JDK9 features. I have my colleague Viber also here. And ask anything. This is some of the important mailers. You can, this is an open JDK mailer. Anybody can subscribe. I see frequently actually many college interns, right? Even this and mailers, mails to JDK9 devs requesting like additional information, how to use this and that. It's a very active mailer groups. So don't hesitate to ask any questions. Any, like it may be trivial, be it so, but you can still ask. Have any questions in general? I think maybe if I am not wrong, maybe I think 20%, at least 20% of the people have used JDK9 here, right? I mean, I know many of the speakers have been using it, JDK9 has tried. But maybe I know actually many community, right? I see, like there is some nervousness actually upgrading to nine because things might break and may not work completely. And yeah, there is another important aspect. Maybe I will answer this question actually for you. Versioning this deliberately ignored actually in modules because it was identified as a bigger problem than to solve than the modules itself. So there is nothing like you can mention version name in the modules. So you cannot have multiple modules with the same name basically. Have any more questions? And I think there was one question. I'm like, it was in the other session actually, but maybe I'll try to answer here. Maybe like if you are like a container writer, right? You are deploying multiple web apps. You has container manager multiple web apps there, right? And each of the web app may be using different versions of the same jar file. Then how does it handle, how do we handle such case? Modules as itself doesn't allow versioning to specify version information and JDK just comes out if it sees modules with same name. I mean any module with the same name, right? So there is another concept called layers. You can define layer of class loaders actually. This is on top of the boot class loader. You can define layer of class loaders which can confine the modules to one particular application and then extend that pain. Yep, yep. Though I'm not the right person, but all I could say is highly may not happen actually. But the command line tool is as powerful as that. Programmatic API itself is only experimental actually. If you see that slides, right? Even the modules image that is generated, right? The format is kept completely confidential actually. You cannot access. You cannot use any tools to browse through that modules file. There is a way called, they defined the JRPFS actually is a file system API. You can use those file system API to go through those, or the list of modules and all. That is the only way mechanism to access the modules directly. Anything? Done. Thank you. Thank you for your time.