Modular Development with JDK 9 by Alex Buckley

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] okay hi everyone my name is Alex Buckley I work in the Java platform group at Oracle this is modular development with JDK 9 thank you for coming Jenny k-9 is fast approaching and there's a lot in it some of the features are performance improvements such as compact strings some are tooling improvements like the search box in Java doc has anyone seen that by the way into the canine the search box some it's pretty cool the J shell tool does anyone tried that good yep and of course there are lots of updates to existing features such as support for Unicode 8 but the main feature and the one that's taken some years to come to fruition is the module system the module system is a big deal because it enables modular development all the way down the module system is built into the Java language and the Java Virtual Machine so that the applications you write and the libraries you consume and even the JDK itself can all be developed and tested and packaged and deployed as modules managed by the module system making everyone play by the same modular rules has great benefits for reliability maintainability and security as we'll see in the rest of this talk so with the theme of modules all the way down in mind this talk has three parts the first part explains how modules are a long-overdue building block in the structure of application code the second part is about how applications and the libraries data pendin can migrate to modules more broadly it's about how you can mix modular code and on modular code the third part is about the structure of the modular JDK including some of the compatibility issues that arise from it so programming in the large modular applications in object-oriented programming the basic unit of reuse is traditionally the class programs or classes Java has wonderful mechanisms for promoting reuse of a class inheritance for reusing behavior interfaces for reusing abstractions separate compilation dynamic linking and access control all the way down to the level of individual fields and methods and we've had nested classes since 1997 so it should be possible for a single top-level class to encapsulate a vast amount of functionality with that in mind I'm setting up a strawman here but keep going with that in mind it seems like an application could be a single package containing a few very rich classes all sharing data via fields and methods accessible within the package and where a handful of public classes form the entry points or the API of the application right not really how many people work on a code base that consists in your application of one package no hands right answer two packages three packages five order of ten packages in your codebase one we have a few on the order of 10 a 17 ok at least minute right right right everyone knows the minimum but who knows the maximum order of perhaps 50 packages there's that there are some hands maybe some hands the are sort of shooting up just just your codes your short digital code now the point is no one uses a handful of packages anymore even the smallest microservice wouldn't be expected to fit into a single package programs are packages multiple packages not classes unfortunately the Java language kind of gives up once your program is bigger than a package here's the hierarchy of accessibility in Java it's simple to understand easy to use and strongly enforced at compile-time and run-time but it has a big weakness your program is some dozens of packages but the only way to share code between packages is by making things public but then you're sharing with everyone it's not surprising that packaged friendship in one form or another has been requested many times over the years a package is a fine way to organize classes but most people wish there was a way to organize packages too now of course you can put some packages in one jar file and other packages in another jar file and so on but that's after compilation it doesn't help you control access from one package to another during development wouldn't you prefer to group your packages in a logical fashion when you're actually developing them nodding heads perhaps yeah good thinking as to that yes there are some nodding heads in the audience that brings me to modules in JDK 9 a module in JDK 9 is a set of packages that make sense being grouped together this is the classic software engineering principle of high cohesion some of the packages are intended for use by code outside the module these are exported packages some of the packages are internal to the module they can be used by code inside the module but not by code outside these are concealed packages now the word use keeps coming up used by use by use by this code a module is the unit of reuse it describes which of its packages of external use and which are concealed internal use a program built of modules will be more reliable than a program built of a loose set of packages that can access each other freely and that exposed to many AP is to the outside world let's look at the Java base module this is the foundation in gdk9 of the Java rescue platform it it grouped the essential Java star and Java X dot star packages that most programs need it's where java.lang object and Java IO file and Java util list live it declared in a file called module info Java this gives the name of the module and its exported packages what does it mean to export the java.lang package it means that the public classes of java.lang are accessible to code outside this module a package that is not explicitly exported is concealed in the java base module in in red many comments on and some packages are concealed their public classes are not accessible from outside the Java based module this is the first goal of the module system strong encapsulation a module isn't just a set of packages it's a set of exported packages and conceals packages the public classes of exported packages are accessible outside the module the public classes of concealed packages are not accessible outside the module so the hierarchy of accessibility is bigger in jdk 9 than in jdk AIDS reading upwards on the right you can arrange for public classes to be accessible only within their module or accessible within their module and to other specific modules or accessible to everyone so to be clear in jeddah key 9 if you're looking at public on the class declaration it no longer means that everyone can access the class access depends on whether the class is module export the class's package since Java base is a module let's reuse it with a module of our own here's the simplest possible program in one package komm example hello let's declare a module to put that package in hello world there's a module in photo Java file and for sake of argument the module will export the calm example Hello package with the exports directive you're probably wondering how the hello world module knows that it has a package called comm example hello after all nothing in the package seems to point to the module it's up to the tooling to decide during development which module each package belongs to in practice your IDE will take care of it you'll create a modular job or application be asked the name of the module then every package you create will just be passed to that module let's know they're there it just happens if you run Java C by hands then Java C figures out which module each package is in that's why the module info Java file is at the same level in SRC as the common directory containing the package the benefit of relying on tooling is that it's really easy to place an existing package in a module and immediately give that package the benefit of strong encapsulation we don't want each and every class to have to opt in to strongly encapsulation by declaring the module it belongs to that would invite errors such as classes in the same package attempting to join different modules that's a big no-no for reasons I'll mention later one more thing the say hello class in the package imports the java.lang package where is that package imported from now you might say Alex the answer is obviously Java base because you told me a minute ago the Java based exports the java.lang package I had a slide that showed it and your rights but how does the compiler know that in general when you import a package should the compiler search the file system looking for modules which export to imported package what if multiple modules export the imported package obviously java.lang is a special case but in general how would a compiler know which module exports a package if we intend to reuse the Java based module we should document that fact actually since we're writing a module ourselves we must document that fact this is the second goal of the module system reliable dependencies a module isn't just a set of packages it's a set of packages that depend on the packages exported by other modules so the HelloWorld module specifies that it reuses the Java based module with a requires directive in its module in photo Java this means that code in the HelloWorld module can import any of the packages exported by Java base what happens if code in hello world tries to import any of the packages conceals by Java base such as and there's one in red some security provider here's a real example of some code that does that GlassFish 4.1 it doesn't run on jdk 9 because the VM throws an illegal access error the error message is a class concern enterprise security provide a policy wrapper in module unnamed module don't worry bailout cannot access class some security provide a policy file in module Java base now a glance at the open JDK repository shows us that the policy file class is declared public in the sun security provider package but because that package is not exported by java base policy file is only accessible from code in java base itself so to be clear in jetty k9 the GlassFish code cannot access the public policy file class at compile time or runtime it's exactly like trying to access a package private class from outside the package Java C gives an error the VM throws in a legal access error GlassFish will need to find a supported API not a Sun dot star API to do its work I'd like to return to the module Inferno Java file that declares the hello world module it's really important to understand that a module exports packages but it requires modules the reason is due to an old software engineering principle the unit of reuse is the unit of release the principle is about separation of concerns you reuse someone's code not by copy pasting it into your own source tree but by depending in some way on the black box artifact released by someone else now in the Java ecosystem there's no question that the unit of release is a jar file that doesn't change with modules a jar file as HelloWorld aa jar that's what you built today simply carries the module info dot class file that a compiler produced from module in photo Java alongside an ordinary class files like say hello we call this a modular jar so when someone releases a modular jar for their module its reused by someone else writing requires hello world in their own module in futur Java the re user benefits from an explicit coherent API consisting of precisely the exported packages the releaser benefits from strong encapsulation of conceals packages inside the module which underpin the API even if there's high coupling inside a module there's loose coupling between modules that's another good software engineering principle so as the release are you're exporting packages but as the reuse err you're you're consuming modules ok so you want to require Java base from your HelloWorld module when you say requires Java base in module in photo Java where does the compiler physically look for it and if you've built the modular jar file for HelloWorld jar containing module in photo class where do you physically put that jar well JDK 9 looks for modules in the system image and on the module path the system image is in the JDK installation directory it contains Java base and a few dozen core JDK modules the module path is set on the command line like the class path except that the module path points to directories containing modular jars rather than the jars themselves which is pretty convenient it makes the the module pastor says looking at the libs and there's a whole bunch of there are hundreds of modular jars perhaps in each directory now the key point about modules requiring each other is that the module system can check the requirements and validate that a modular application is sound once the compiler or runtime has found the initial hello world module my not benign assembles in the system image or on the module path it performs a process called resolution resolution means inspecting it requires directives and finding those required modules in the system image or on the module path and then recursively resolving them we're building a graph whose nodes are modules and whose edges are the requires relation and to be clear in JDK 9 we do this at compile-time and run-time if resolutions succeed you get three guarantees first every module that is required is available okay pretty obvious but a big improvement over the class path where you don't discover missing jars until later seconds modules don't depend on each other in a cycle cyclic dependencies are a design smell and we're taking the opportunity to prohibit them in modules from day one of JDK 9 now some of you are thinking Alex this is just dependency management haven't you heard of maven who is thinking that you're definitely not but definitely not thinking of an elephant you're not thinking sure cyclic dependences are well yeah now let me say maven only works at compile time and this resolution process works at runtime as well but more importantly let me come to resolutions third guarantee if coding one module imports a package then that package is exported from exactly one other module now this guarantee obviously relies on exports as well as requires so you won't find it in maven it means there are no splits packages which is what happens when two jars on the classpath contained the same package and you load some classes in the package from one jar and other classes in the package from the other jar split packages are a huge failing of the class path mechanism because they lead to incredibly difficult to debug scenarios because of resolution they are completely impossible in a modular application which is great for long term maintenance and this is really what we mean by reliable dependencies the dependencies in a graph of modules are reliable when each module can access only one version of a package at a time and the third guarantee is a big deal for performance too because we know which module exports which package there's no need to scan every module in the system image and on the module path when trying to load a class contrast that with how you load classes from the class path this is the class path some of you Mason's before the class path from Hadoop the compiler or runtime has to do a linear search through 110 jars whenever a new class is needed now of course the implementation can speed things up by caching the classes it found when it wasn't looking for them but they're still the same nasty half here half their problem of packages split across multiple jars in fact if you think about it the class path is crazy with a hundred and ten jars there are over 12,000 possible interactions between classes in different jars each one starting a linear search the classpath is the ultimate in AirAsia whatever you know about the structure of your application the classpath throws it away and connect every jar to every other jar with modules a module info Java you're telling resolution what you know about the structure of your application and it uses that information to provide safety and performance at both compile-time and run-time now with all of this talk of dependencies and resolution and the module path I know what you're thinking where are the version numbers who is thinking where are the version numbers yes a number of people are think you where the version numbers can my module and the world require x and y where x requires version 1 of some library and y requires version 2 of the same library now this is a difficult problem the problem with multiple versions is that a class loader can't have two classes with the same packaging class name now if you're using maven it will and you have some version dependencies it will pick one of the versions for you in which case you are not getting the two versions you thought you were or in some cases depending on the artifact names it'll put them both on the class path in which case you get the split package problem now you've been thinking it's possible with maven to have multiple versions because no one stopped you from doing it but in reality you cannot do it without playing games with class loaders which maven doesn't do now if you do play the game where every module is loaded in its own class loader you would better make sure the objects from version 1 and version 2 of the library don't leak out to a common caller like hello worlds otherwise you'll get the dreaded class cast exception where you can't cast foo to foo because the foo from library 1 and the food from library 2 are different ok you're thinking this is this seems the complicated problem and class loaders are complicated nevermind multiple versions of a library forget that can I just say that by module one's version 2 of some library and not that buggy version 1 well now you're the why on the slide you want version 2 you're sure of it but you might be your module might be reused in a larger application where someone else is equally sure they want version one so the module system forces you to pick a single version of each module required by the application in module in photo Java you require a module by name not by name in version when the compiler or runtime scans the system image or the module path looking for that named module only the first module of that name is found so just like it's up to the tooling to help you associate packages with a module it's up to the tooling also to help you pick that single version of your dependencies so there's a little more to say about that a lot later if I have time but the thing to remember for now is that a module is a set of packages designed for reuse they offer strong encapsulation and reliable dependencies and module aware tooling will be a big part of the modular development experience moving swiftly on let's talk about how we would take an existing application and migrate it to modules now since it's impossible to modularize the Java ecosystem all at once we're going to be living with a combination of modular code that's modular jars on the module path and non modular code that traditional jars I don't wanna call them I don't want to call them legacy jars they're just jars on the classpath for a while that's fine and JDK 9 has tools for easing the migration that's what this section is about so we'll start with a simple application that we want to migrate from the class path at heart it has three layers at the top of your application jars might be more than one of these because you've got so many packages right at the bottom is the JDK and in the middle there's a bunch of library jars downloaded from the internet and thrown on the class path now I've hinted that we've turned the JDK into modules and in this section green boxes will represent modules you've already seen Java base and you won't be surprised to learn there are also modules for logging database access XML processing Java logging Java sequel Java XML and many more but our application isn't modularized and nor any of the libraries should we monitor eyes the application it's up to you you can just run it on the class path like you always did class path is not going away in jeddah k9 but we modularized the jdk for a reason to improve security through strong encapsulation and stability through reliable dependences applications might want to benefit from this just like the jdk does there's nothing special about the jdk modules so just modules so let's see how we might turn this application into modules let's imagine the application is in two jars main code in my app jar helper code in my lib jar and let's also imagine that the soup of library jars is limited to jackson the JSON processing library jackson comes as three jars core data bind and annotations and we have the modular jdk on the bottom this is how we'd run the application today we've got to set up the Lib directory to include our application jars and our library jars pointing the class path out of them then run the application using the java launcher one of the things we'd gain by modularizing is not having to list out the dependencies on the command-line in script and where they can typos no one will detect anything's wrong until much later so let's look at a scenario for migrating this application top down here we first modularize the application jars without modularizing the library jars now in general if you depend on third-party libraries you're depending on them to modularize and we can make it easier for libraries to modularize but generally we all have to wait for them to do it no one can force them so it may well be that some of the libraries you depend on are not modularized yet that's okay now for your application jars that you do control the obvious path is to turn them one-to-one into modular jars where each jar has a module in photo class file this is not always possible especially if the code in the jars has cyclic dependencies but let's go with it for now now if we're going to turn each application jar into a modular jar we'll need to write a module declaration in module in photo Java that gives a name a list of required modules and a list of exported packages the names are easy my after my Lib we don't yet know though what each module depends on we can make manual analysis of the source files of the class files but there's an easier way the Jade EPS tool Jade EPS scans class files or jar files and tells you what code from other jar files that code depends on now Jade EPS actually came with JDK 8 and there's an improved version in JDK 9 now while this isn't a perfect solution come on to that it's a pretty good start so we'll run Jade Epps on the application jars the Jackson libraries are assumes to be on the class path here and we see that my app jar depends on two of the Jackson jars which remember and not modularized yet this is just looking at the the references in bytecode and of course on my little jar plus my app jar depends on the JDK modules Java base and Java sequel say my live jar only depends on Java base so that's nice and simple now we can write our module declarations let's start with the easy one the helper code in my lib we know it depends on Java base we can write requires Java base though I've sort of been stringing you along you don't have to it's always put in for you by the compiler because every Java program ultimately relies on java.lang objects so you always what you cannot not require Java base and from the Jade EPS run we we knew that my app jar depends on my lip if we'd run Jade Epps with more options we'd have seen that in particular my app jar needs a particular package in my Lib now we could write exports a package in this module declaration to allow anyone access the package but if we're sure that no one except my app will need access we can use a qualified export to maximize the encapsulation to say that package there is exported only to code in my app let's turn to the module declaration for my app it requires my lib no surprise and some JDK modules and we know it's going to use Jackson but we're not sure yet how to write the requires directives because they're not modules yet does that mean that we which means you have to turn Jackson into modules before you can write this declaration that would be unfortunate since we you don't control the Jackson jar files if only there was some way for the Jackson jar files to somehow become modules automatically look how green they're going we don't know we didn't write Jackson we don't know what their dependencies and exports would be but we have a pretty good idea of what the names would be they basically be the same names as the jars if we could do that we could finish writing the module declaration for my app happy faces on those requires directives we'd have a lovely module graph with my app depending on my lib and Jackson Koren Jackson data bind and Java base and Java sequel and my Lib depending on Java base the good news is we can do this with automatic modules an automatic module is a module whose declaration is inferred by the module system from a traditional jar that you have placed on the convert module path they're real modules there they're really there at runtime you don't change the jar file I can get this across enough you don't change the jar file in any way because you don't know anything about what it's doing the module name of an automatic module that you require is derived from the jar file name it exports all this packages and it requires all other modules in effect automatic modules mean that today's jars are already tomorrow modules now once automatic modules spring into existence for Jackson core Jackson data binds and Jackson annotation because you move you put those jars on the module path the module graph looks quite different because the automatic modules basically say requires everything they require each other they require all the modules in the JDK image and they require all of your modules as well and they explore all their packages now this might not be the set of requires and exports that the Jackson maintainer x' would write by hands um but it's actually the way automatic modules do this is a feature not a bug because it emulates the behavior of the classpath it provides the maximum possible compatibility surface for code in jar files and it's actually better than when everything was a jar on the classpath for example you have to look carefully there is no arrow from my lib to my app so there's no danger of helper code in my Lib accidentally reaching into my apps internals on the classpath code in my live jar could access code in my app dot jar my lip dot jar could access code in my aperture quite easily without really even knowing it and that causes maintenance headaches down the road now you might think we could do better perhaps the module system could run Jade EPS on the Jackson jars at startup and try to figure out what modules the Jax and jars require unfortunately this wouldn't really help the reason is that libraries like Jackson often make use of core reflection the java.lang reflect API to inspect application classes dynamically Jade EPS can see the use of core reflection but it can't predict statically what classes will be inspected dynamically and in fact the Jackson Beta bind module does exactly this kind of reflection it's going to grow all over your application classes so it can convert between them and JSON documents so if my app has classes for which it wants Jax and data binding we want the effect of saying that Jax and data bind requires my app amongst many other things that's exactly what automatic modules give you is one more wrinkle when code that was that was Jackson going up to my app when code in my app calls the Jackson API it passes its own class object there it is the far right the intent is that Jackson data bind can create an instance of that application class my value and then reflectively set the name and age fields of this my value instance based on the content of this here JSON document however this code fails because we never got around to saying what my app exports to Jackson data binds now this in some sense is is gentle because my app doesn't really have an API it's an application but if it wants to allow Jackson to manipulate instances of its classes by reflection then my app still need to export some packages strong encapsulation applies not only to references from one module turn to another compile time but also for reflective access at runtime if a module doesn't export a package then code in other modules can't inspect the classes by reflection now a reflective relationship between application code and library code is common application containers might walk over classes to find annotated methods to be exposed as endpoints dependency injection frameworks will call your methods reflectively serialization frameworks will reflectively create and modify instances of your classes many applications use these facilities and in order for them to work we somehow have to expose otherwise encapsulated application classes via reflection now we could do that by exporting the application packages but there's a finer-grained mechanism that is specific to access by reflection that mechanism is the open directive so let's say our domain classes like my value are in this comm my app domain package we can open that package up for access by reflection to all modules or we can qualify the opens just like we did for exports before opening a package is narrower and deeper than exporting a package narrower because opens only has an effect at runtime whereas exports applies at compile-time and run-time but deeper because opens allows all elements of that package to be accessed by reflection whereas exports only allows reflective access to public elements it sort of a lot simpler to use than to explain in some ways we could go in the other direction to rather than opening a specific package for reflection we could open all of our my app packages for reflection by anyone you declare you could declare my app as an open module open modules give you half the benefits of modularity you get reliable dependencies all the requires clauses will get resolved at compile-time and run-time but not strong encapsulation because anyone can reflect their way into the private fields and methods of my app but since frameworks that reflect deeply into application code are a reality in everyday Java development application code can't always be strongly encapsulated and open modules we think are a pragmatic solution it's up to the application a developer to choose note that this open module doesn't but an open module can still use exports directives in module inferred Java to define and of a static API for use at compile time and now we can run our modular application with a simple invocation assume our modular jars that's my app jar and my libs are and now in EM lip and the unchanged Jaxon jars are still in Lib we just have to tell the Java launcher where the module pass should be set and it will figure out which of the jars on the module path should be turned into automatic modules so when you migrate each application jar is usually a good candidate to be a module each library jar will migrate at its own pace and automatic modules mean you are not waiting for the weakest link that would be very sad we had to do that nearly there let's talk about the the JDK roughly speaking the size of the Java platform has been going up with the square of the major version number Java 1.0 had only a few hundred classes Java 9 is tens of thousands the JDK 1.0 download it it still installs and no 7 was under 4 Meg the JDK 9 download is a hundred and 50 Meg now when the Java platform was small the organization of the JDK code wasn't a problem but every year the platform grew a little bigger and now it's huge and monolithic in reality the Java platform is not one thing it's more like 25 separate frameworks including the swing UI framework the crypto framework scripting framework multiple xml processing frameworks and so on there's no reason these separate frameworks have to be so tightly coupled in one download in fact it's an impediment for us in developing the JDK the overly tight coupling raises development and testing costs which turns into slower platform evolution plus the larger the surface of your platform more difficult it is to secure and it's an impediment to lots of users both those who want to run their applications on smaller devices and those who want to run more instances of their application on large systems even if you only want a part of the JDK you've got to take all of it the good news of course is that JDK 9 is modular we've taken the monolithic RT jar file and broken it up into a few dozen modules some of these are part of the Java SE specification some are just just parts of the jdk implementation here's a graph of the Java SE modules we can see at the bottom there's Java base which everything depends on and which depends on nothing itself we've broken out the various frameworks into their own modules instrumentation logging XML scripting etc which you can use by requires or not as your needs dictate at the top there's a Java SE module which has no actual code in it but just has dependencies so you can say requires Java SE and be guaranteed to have all of these modules available it's worth mentioning that merely finding these module boundaries which might be obvious in hindsight will they tremendous engineering efforts decoupling a monolith is much harder than building a decoupled system from the beginning we had to undo years of bad assumptions and accidental couplings inside our tea jar but going forward the discipline imposed by the module system will prevent us from accidentally sliding back into a big ball of mud I mean a monolith the difference between solid lines and dotted lines is an excellent question we should discuss later the Java SE modules are actually a small subset of the modules you'll find in the JDK 9 system image if you do Java - - list modules you'll see those two dozen or so in Java SE modules Java based sequel logging etc as well as some Java FX modules and then a large number of JDK specific modules JDK compiler JDK Java doc dedicate J shell jdk Jade EPS is its own module the Jade EPS tool is a column in the middle and so on and so on they're all located in the system image but apart from that they're just ordinary modules with requires and exports directives like any other I'd like to spend some time by which I mean the remaining time on expectations of compatibility from JDK 9 this applies to everyone here and it doesn't because you're not the ones who necessarily relying on some of this stuff but it's worth everyone understanding what's going on here some misc base64 encode and some misc base64 decoder does anyone use them oh that was more how I was expecting no hands I was going to say are but all of your libraries do but okay so those classes are gone in JDK 9 they are not strongly encapsulated they're physically not there so this met this might break some libraries that you use if it does file a bug with the library maintainer z' and tell them to use the excellent base64 class introduced in JDK 8 second who uses some miss gun safe same hands are different hands okay so some mystic on safe has not gone away the Sun misc package is exported by a JDK module to the hand supported and the unsafe class is still there however while the Sun misc package is exported many JDK internal packages are not and again this might break some libraries that you use because library code will fail if it tries to access classes in the concealed package common crypto Sun provider or comma Sun or the patch is X YZ internal Jax P or Sun nioh CH or Sun net www or Sun reflect annotation or some security x.509 and most of you don't care about any of these packages but the person who does has a problem finally we need to talk again about exports exporting a package means you can compile and run against the public members of the public classes of that package it's an API exporting a package either from a Java mounted JDK module or from your module is not about letting library code use reflection to access private elements if you recall that was what an open module allowed but none of the JDK modules are open let me give you an example the Java based module exports a package called Java dot security which contains a public class called key store the purpose of this class when I find my pointer the purpose of this class is and I quote a storage facility for cryptographic keys and certificates if ever there was a public class in an API whose private fields should be strongly encapsulated it's this one well here is a stack overflow question from July 2016 someone this is on JDK 8 was using reflection to access a private field in the keystore class and not only did this person feel free to reflect over key stores internals they actually got annoyed when the internals were changed in a JDK update a JDK 8 updates the Java security package in JDK 9 is exported so you can code against the keystore api not so that you can reflect over key stores internals one of the reasons we think strong encapsulation is so important is that it will let us evolve the JDK more rapidly and reliably because we all know that no one can rely on unspecified implementation details unfortunately of course there's there's this this guy's basically writing a library there's library code out there which has been relying on these details for years so there's going to be some migration pain for these libraries and for the applications that rely on these libraries if this happens to your hap Legation then again please file a bug with the library maintenance finally finally I again just want to make you aware that some internal aspects of the JDK have been overhauled and again it probably won't affect you but it might affect the libraries and tools you rely on code that assumes there's a file called RTO Jarl tools jar in a particular directory will fail on JDK 9 scripts that try to patch the JDK with - X blue class path slash P will fail on JDK 9 code that assumes the application class loader is a URL class loader will fail on JDK 9 code that assumes all JDK classes are defined by the strap loader will fail on JDK 9 code that assumes the version strings reported by system properties begin with one dots will fail on JDK 9 again if you see libraries failing due to these assumptions on never documented never specified never standardized implementation details file a bug with the library maintenance so the modular JDK is modules all the way down some misc is exported JDK internal packages are nots and beware of libraries relying on JDK internals in JDK 9 a module is a set of packages designed for reuse automatic modules help migrates libraries and with modules the JDK can evolve more rapidly and reliably but popular libraries and tooling are not yet all compatible with JDK 9 in the 2 minutes remaining for the network the last two slides and all of your questions are I need to acknowledge that there's a huge amount in the module system that I haven't had time to talk about you can encapsulate resources in a module largest classes you can express optional dependencies by programming with services you can build custom system images with the j-link tool so you can drop CORBA right now if you want and you can in fact spin up multiple versions of a module with the layer API if you're interested in this kind of thing it recommends two books the first is Java 9 modularity out now in early access form it's a very pragmatic walkthrough of the entire module system and the modular JDK the other book is java application architecture from 2012 it's a principled look at constructing modular applications it says I was joined the title it's it's not specific to any module system really it has a lot of very very good advice that applies whether you're using a module system or just relying on traditional jars about how to structure an application so the best thing you can do to prepare for jdk 9 is download an early access binary has anyone done that some hands okay some hand thank you if you're a library maintainer these runge a depth to see what JDK internals you rely on you can do this right now on JDK 8 that will that will work on JDK AIDS everything you ever wanted to know about the module system is discussed on open JDK in jet 261 I cannot emphasize enough how much valuable information lives in jet 261 there's also jet 260 which identifies the JDK internal classes like some miss gun safe that are exposed in JDK 9 jet 223 which defines the new version strings beginning 9 dots and jet 220 which describes how RT jar has gone away finally jet 200 gives an overview of the JDK modules but if you've already read jet 261 which should because it's very good there won't be any surprises and with that exactly the time thank you very much so we now have negative time for questions so we all tealights you someone had you had a question earlier do this quickly versions of a jar in Jeddah k-8 on the class path you would typically shade the packages that that will continue to work jar files both on the class path and modular jar files on the module path there's nothing that thus better the specialness is all in the module info dot class file the contents of those module if they are in fact containing renamed rebased your word packages fine if your if you have if you have shaded the package and renamed it even if it's being exported the there are different they're different classes that was a question you had a question hey al how do you test classes that are not exported there are this is this is a talk in itself the short answer is there is a command line flag to patch classes into a module so you can access the internals GEB 261 has all the information about that the real answer is that testing frameworks that wish to test non-public non exported non open elements of a module should use the method handles lookup API to access module internals in a constrained way that is that is an entire days worth of talk but you it only requires the testing framework to spin its infrastructure once to use the write API I'm a question from the back yes was what the qualified export was let me go back that export exports the package to a specific friend module yes I think that is all we have time for again thank you [Music]
Info
Channel: Devoxx
Views: 15,226
Rating: undefined out of 5
Keywords: DVUS17
Id: rfOjch4p0Po
Channel Id: undefined
Length: 53min 12sec (3192 seconds)
Published: Mon Apr 17 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.