Comment by alex_smart
Comment by alex_smart 3 days ago
Why so much hate for modules? They seem to be almost universally disliked by everyone on this thread and I don't understand why.
Comment by alex_smart 3 days ago
Why so much hate for modules? They seem to be almost universally disliked by everyone on this thread and I don't understand why.
The use case for modules is to have a unit of organizing code (deciding what is visible and accessible to who) at a higher level of abstraction than a package. It allows library authors to be much more explicit about what is the public API of their library.
Ever wrote "List" in Intellij and instead of importing "java.util.List" Intellij prompts you to choose between like twenty different options from all the libraries you have included in your classpath that have implemented a public class named "List"? Most likely 90% of the libraries did not even want to expose their internal "List" class to the world like that but they got leaked into your classpath just because java didn't have a way to limit visibility of classes beyond packages.
Yes, but at what cost? Many libraries can solve visibility problem with package level visibility. And modules cost a lot: dependency management was a non-goal for them, so anyone who wants to use module path instead of classpath, has to declare dependencies twice. It was a big mistake not to integrate modules with a de facto standard of Maven.
> Many libraries can solve visibility problem with package level visibility
The only way of doing this would be to put all classes in the same package. Any nontrivial library would have hundreds of classes. How is that a practical solution?
Well designed non-trivial libraries should be open for extension and thus should not hide most of the implementation details, leaving the risk of too tight coupling to users. E.g. if I‘m not 100% satisfied with some feature of a library, I should be able to create a slightly modified copy of implementation of some class, reusing all internal utilities, without forking it. So no, modules as means to reduce visibility are not as cool as you think. And given the specific example of the list, it’s possible to filter out irrelevant suggestions for auto-complete or auto-import in IDE settings.
Directly or indirectly many (or most) projects ended up depending on something which was using an unsupported backdoor API because it provided a marginally useful capability. The module system restricted access to these APIs and everything stopped working, unless you added some magic command line arguments to gain access again.
So for most people, the initial impression of modules is negative, and then they just decided to rule the feature out completely. This has created a sea of useless criticism, and any constructive criticism is hardly observed. Improvements to module configuration (combine it with the classpath), would go a long way towards making modules "just work" without the naysayers getting in the way.
>Directly or indirectly many (or most) projects ended up depending on something which was using an unsupported backdoor API because it provided a marginally useful capability. The module system restricted access to these APIs and everything stopped working, unless you added some magic command line arguments to gain access again.
Is it even theoretically possible for a project like this to not run into these kind of issues? Like literally the project's goal is to enable library authors to be more explicit about their public API. So breaking use cases that use unsupported backdoor APIs very much seems like a predictable and expected result?
Early on there were things you couldn't do without using com.sun.* classes, so people got used to doing that. It's been many years since that was all fixed, though.
I have a company with ~20 developers only. And already I have an ArchUnit test stating that public classes within "com.companyname.module.somepackage.internal" cannot be used anywhere outside "com.companyname.module.somepackage".
Surely almost everyone who has worked in a large enough codebase and thought about large-scale modularity can see the use case for a unit of abstraction in java higher than a package?
Yes, in theory they are good. In practice they cause enormous amounts of pain and work for library maintainers with little benefit to them (often only downsides). So, many libraries don’t support them and they are very hard to adopt incrementally. I tried to convert a library I maintain to be a module and it was weeks of work which I then gave up and reverted. As one library author said to me “JPMS is for the JDK itself, ignore it in user code”.
Given how much of a coach and horses modules drove through backwards compatibility it also kind of gives the lie to the idea that that explains why so many other language features are so poorly designed.
They're fine, but they're incompatible with building fat-jars ro have single file deployment and dead to me because of that. Spring does some ugly jar-in-jar custom classloader stuff which I hate out of principle because it's spring.
Oracle hates that people build fat-jars and refuses to adress the huge benefit of single file deployables.
Modules are weird. In Java world there exists consensus on dependency management via Maven-style repositories (Maven Central is the primary distribution channel) and all tools support it. You handle your dependency tree outside of your code and just import packages from libraries available on classpath. It’s possible to continue doing that that without using modules, so the case for using them is still unclear to many people. Where the actual hate may have come from is an old story with migration from Java 8 to Java 9, where modules hidden the access to certain internal APIs, breaking some libraries which relied on them, making that migration painful. Today their value is probably 0/10, but there’s no reason to hate.