Win a copy of Testing JavaScript Applications this week in the HTML Pages with CSS and JavaScript forum!

Nicolai Parlog

Greenhorn
+ Follow
since Aug 05, 2019
Cows and Likes
Cows
Total received
6
In last 30 days
0
Total given
0
Likes
Total received
7
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Nicolai Parlog

Hey everyone, it was fun to be here. I have too many balls in the air as it is, though, so I won't regularly scan the forum. If you have any questions or want to get in touch, hit me up on Twitter - I'm @nipafx. πŸ‘‹
11 months ago
Those two are pretty significant, but there are indeed a few more:

  • strong encapsulation will improve security of the platform and maintainability of the platform and all projects that start using it
  • building a module graph may improve launch performance (I assume, not much, though)
  • with jlink you can create runtime images that only contain the Java module you want or images that include your entire application


  • That said, I think if someone doesn't buy the module system for strong encapsulation alone, they're unlikely to buy it as a whole.
    11 months ago
    Hi Brecht, I'm not going to stop you from buying my book πŸ˜€, but I honestly think there may be better avenues for you to take.

    It is good to know that the book is also a good resource for beginning programmers



    I understand this to mean that you consider yourself a beginning programmer. If that's the case, I recommend you conquer other areas before coming to the module system. While understanding how it works does not require a lot of prior knowledge, if you don't have a few years of experience with Java, it may be hard to see what it's good for and which problems it fixes. Since you're currently dealing with Java 8, I assume your head is full of lambdas and streams - Functional Programming in Java may be a good next step to take.

    On the other hand, if you don't "just" learn to qualify for a job (there would be nothing wrong with that) and are ok with not immediately seeing a return of the invested time, why not learn about the module system after all? πŸ˜‰
    11 months ago

    Please correct me if i am wrong in comparing both these statements



    You're correct, Oracle's statement and mine describe the same mechanism and performance improvement.
    11 months ago
    On Java 9+, the module system is always in play and there's nothing you can do about it. That is most obvious when you try to compile code that imports a class from an internal API (e.g. from a sun.* package) on such a version - it will fail due to strong encapsulation of (JDK) modules (unless you add JPMS-specific command line arguments).

    But: You don't have to create modules at all. As long as you place your code and your dependencies on the class path, they all end up in the so-called unnamed module and there will be no encapsulation between them, the module system will not check presence of dependencies, split packages are ok, and so on and so forth. As the JDK team put it, "the chaos of the class path" lives on inside the unnamed module. But that doesn't mean the module system is not active - it is, just not within your code.
    11 months ago

    and helped a little with the book



    That's quite the understatement! Jeanne did more than "just" edit during my writing process, she also reviewed Manning's copy-editing (which must have been a lot of work), when I denied to do it. Without you, the book would still sit in copy-editing, so thank you for that.
    11 months ago
    That's a good question - I don't know. But the trade-offs are different depending on whether you run your code yourself or your customers run it.

    If you run your code yourself, you have full control over the deployment pipeline and jlink-ing your code and dependencies with JDK modules into a runnable artifact basically just moves infrastructure code around. You still have to define which Java version to run on and your a launch script and so on, but with jlink you can do that in the "Java realm", whereas with docker you do it the "Docker realm". Not a big difference, I would assume. (That said, jlink allows you to apply a few optimizations that reduce image size and slightly improve launch performance, but that's minor.)

    If your customers run your code, jlink is an entirely different beast. With it, you deliver a runnable artifact that operates independently of any installed JRE (if there even is one). That's great because you can pick the exact Java version that you want to support and nobody can screw with that. Then again, it's also somewhat terrifying because customers can no longer independently update their Java version (well, they can, but your app doesn't care). That means if there's a security fix, you need to provide a new application image immediately. And that's like to come with an application update, too, so your customer better be prepared for that at any time.

    I think there's a fair share of Java projects that can benefit from jlink, but how large that share is? Once again: no idea.
    11 months ago

    My question is does the book include a comparison of the performance of an application that is written with modules against an application that doesn't use modules?



    No, it doesn't. As Jorge correctly points out, the module system isn't about performance and it has very little impact on it. It's not zero, though. First of all, the module system applies a number of checks at launch time and that takes a little time of course. On the plus side, it indexes JARs on the module path by the packages they contain, making class-loading a little faster because the loader knows which JAR to check for which package. Both of them have negligible impact on launch performance and no impact on peak performance. If you care about the former, take a look at application class-data sharing and at Graal's ahead-of-time compiler.
    11 months ago
    @Will: I think Campbell answered your second question, but I'm not sure I get the first. To me the term "packaging" means "putting bytecode into a JAR", but I think you mean something else, right? If you're thinking about putting a bunch of modules into a runtime image, then, yes, that's something the module system allows you to do - have a look at the jlink documentation for more on that. Or ask here. And in case I misunderstood you, please clarify and I'll try to answer.

    @Sai: Sure thing.
    11 months ago

    To what extend it's possible to migrate a legacy application without the need to make code changes to the code base, apart from setting the proper VM properties?



    With VM options, I assume you mean --add-exports and the like? You should see them for what they are: An escape hatch and an expression of existing technical debt. They should always be the last fix you employ.

    That said, it's hard to answer your question as it is - it really depends on the project. But, generally speaking, the larger the project, the more dependencies it has, and the older they are, the higher is the chance that you can not simply dump it on the Java 9 class path and expect it to work. There are a bunch of things that can go wrong (see this thread for a little more detail, or this post for a lot more) and the indicators I mention make it more likely that at least one of them occurs.

    As with everything else, Java modules is not for all applications. When it's NOT recommended, besides the compatibility with application server?



    Just to make this very clear: You don't have to create modules. When it comes to considering whether you want to and how to do it incrementally, have a look at this thread.
    11 months ago
    IntelliJ also has modules. πŸ˜‰

    1. How is this similar and different from modularization provided by Maven and OSGi (though these may not be comparable per se but I wanted to understand from an analogy point of view)



    The central aspect all of these modules have in common is that they are centered around one JAR and (usually) one source tree:

  • in IntelliJ, a module usually contains a single source tree
  • a Maven module compiles, tests, and packages a single source tree (usually) to a JAR
  • for the module system at compile time, a single module-info.java, which is usually bound to a single source tree, defines a module
  • for the module system at run time, a single JAR defines a module
  • for OSGi, a single JAR defines a bundle


  • All of these modules also deal with dependencies and JPMS and OSGi also manage API access. But that's mostly what they have in common. As soon as you get into the details, things differ a lot. Yes, Maven and JPMS manage dependencies, but the former cares about versions, downloads artifacts, and places them on class and module path, whereas the latter simply takes that as input. Yes, JPMS and OSGi manage API access, but the former operates below class loaders and limits accessibility whereas the latter operates on top of class loaders (in fact, that's how OSGi is implemented) and limits visibility. We could go on like this.

    So while it makes sense that all of these tools call the "bag of code" they're working on a "module", the term means different details for each. And that's perfectly ok because each tool has different tasks and thus needs different pieces of information to to fulfill them. While it's not entirely coincidental, we're actually pretty lucky that all of these tools agree on the "1 source tree : 1 JAR : 1 module" relationship, so the term "module" does not mean radically different things in different contexts.

    2. Will these technologies work together and strengthen the notion of modules or do you think they are incompatible?



    While OSGi is a very mature system, it's tool support is far from ubiquitous. It's usually implemented via plugins for IDEs and build tools and users who don't use OSGi don't get in touch with them. Given OSGi's market share that means few developers get in touch with these tools and can use them to learn about their code.

    I really hope this will be different for the module system. It's build into the Java platform's core and everybody interacts with it at least via the unnamed module. Starting to modularize from there will be a fairly natural process and so I hope many teams will do it, which will in turn make tool vendors improve their support. That gives me hope that the ecosystem will strengthen its notion of modules, that tools will converge on a shared understanding, making it easier for developers to think of their projects in these terms.

    But we're definitely not there yet. I recently created a JPMS maturity model that lets us compare module system support by various tools and it makes obvious how much their level of support still differ.

    11 months ago
    I don't know OSGi very well, so take what I say with a big grain of salt.

    Yes, the module system and OSGi have a lot of conceptual overlap. Both turn JARs into modules/bundles by giving them names and letting them define APIs and express dependencies. OSGi goes beyond that, though. It's service model is more refined and it allows bundles to appear and disappear at run time, something Java's module system doesn't even dream of. If you use any of OSGi's more advanced features, there's a fair chance that the module system isn't powerful enough for you. Otherwise, I would prefer the module system because it is better integrated into the platform and tooling (although the latter may take a little more time to mature).

    For what it's worth, Sander Mak, OSGi and JPMS expert, agrees - see here.
    11 months ago
    You are correct. Once you've migrated your Java 8 application to the Java 9+ class path, it runs in the so-called unnamed module whereas all JDK code runs in proper explicit named modules.

    Starting form there, several modularization strategies exist:

  • Top down: You can start with the JAR that contains the application's entry point and turn it into a modular JAR by adding a module-info.java to its source tree. You will then compile and run it from the module path, which forces you to pull its dependencies on the module path as well. If these dependencies are modular JARs, too, their dependencies need to be on the module path as well and so forth. Non-modular JARs that end up on the module path will be so-called automatic modules - their special power is that they can access the unnamed module (explicit modules can't do that) and so their dependencies can stay on the class path. The effect of all this is that, at run time, the top of your dependency tree is an explicit module, some of its dependencies may be as well, but then comes a buffer of automatic modules with most of the other dependencies on the class path. You can then incrementally modularize modules from the top down by adding module declarations and pulling their dependencies onto the module path.
  • Bottom up: Look at a JAR at the bottom of your dependency tree, ideally one with no dependencies outside the JDK and add a module-info.java to its source tree, compile and run it from the module path. The interesting bit is that JARs further up the tree, which are still on the class path, can access it, because they are in the unnamed module, which reads all other modules. You then work your way up the tree.
  • Inside out: Putting these strategies together you could actually start anywhere in your dependency tree and move up- and downwards from there. Heck, you could even throw darts at the tree and modularize every JAR you hit, but there's no point to that.


  • Note that these strategies are more complicated than moving to the module path in one fell swoop. If you can take a modularization day/week and have a developer, a small group, or maybe the entire team do nothing but creating modules so your entire code base gets modularized at once, you will be in a cleaner state. That said, if your dependencies are not fully modularized you're effectively in a top-down scenario where your part of the tree is modules on the module path and you're waiting for your dependencies to catch up.
    11 months ago
    I'm also not sure what you mean by "previous systems" (OSGi maybe?), but I can tell you about the challenges and advantages of "module system" over "no modue system".

    Regarding the challenges, there are two sets of those:

  • migrating from Java 8 tΓΌ Java 9+
  • turning your code into modules


  • The first step is heavily impacted by the module system and you need to know a little bit about it, but it doesn't come from adding modules. It comes from taking your existing Java-8-application and making it work on Java 9+. This step isn't optional and while you can work on it in increments, getting half the way to your goal gets you nothing - you can't be "Java 8.5"-compatible. ;) See my Java 11 migration guide for details on what to expect. Summary:

  • removal of Java EE modules
  • illegal access to internal APIs
  • removal of deprecated APIs and JavaFX
  • casting to URLClassLoader
  • split packages
  • new version strings


  • The second step, taking your Java 9+ application and turning it into modules, can be done incrementally. You can have half your JARs be modules and will reap about half the benefits (I don't have a good source at hand that explains this succinctly). Regarding the benefits, have a look at this thread.


    11 months ago
    Hi Piotr,

    that's a great question to get started. πŸ‘ Here are three benefits you can expect if your entire code base and your dependencies are modularized:

  • Reliable configuration helps you keeping your build intact. Missing dependencies? Duplicate dependencies? Shadowed classes? The module system will let you know.
  • Strong encapsulation prevents you from accidentally relying on your dependencies' internal APIs and helps you to conscientiously structure your own code for better maintainability.
  • module-info.java is a condensed view of your module, making it easy to review and analyze your project's real-life architecture (see this article for a little more detail on that).


  • None of these are mind-blowing features and they're much less exiting than, say, lambda expressions. That's because the module system is not so much a new tool as it's a safety belt and much of its value is not in making you faster, but in managing risk. That's less fun and because its benefit is in preventing rare, but costly problems, the value it provides is basically impossible to measure.

    All of that said, I think it's absolutely worth it. Once an application is modules-only, the module system requires very little attention, so the running cost is really low. (How to get to that state is a different story, though.)

    However, when I look at Jigsaw it seems to me that biggest beneficent will be library providers or some IOT applications that care about minimizing the application size.



    That would be the new command line tool jlink. You can use it to create Java runtime images that contain just the Java modules you need for your application (reducing deployment size) or you can create a runtime image that includes your app (giving you a single deployment unit that doesn't require a JRE/JDK to be installed).
    11 months ago