Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add module-info.java #2970

Open
hrchu opened this issue Oct 18, 2017 · 26 comments
Open

Add module-info.java #2970

hrchu opened this issue Oct 18, 2017 · 26 comments

Comments

@hrchu
Copy link

@hrchu hrchu commented Oct 18, 2017

So that projects depend on this can be published to a public artifact repository.
Note that this is not breaking backward compatibility. All codes except this file can be still compiled in Java 6.

@jbduncan
Copy link
Contributor

@jbduncan jbduncan commented Oct 18, 2017

Guava has an Automatic-Module-Name in its MANIFEST.MF now, so I believe this is not quite as important as it may seem. But if I'm mistaken, then I'd be more than happy to be proven wrong.

(BTW, I think I might have misunderstood something, because module-info.java is Java 9 specific, right? Would a Java 8 compiler (which I believe is what is used to compile guava-jre) or an Android compiler (for guava-android) happily process it or otherwise ignore it?)

@cpovirk
Copy link
Member

@cpovirk cpovirk commented Oct 18, 2017

Our current thinking is that we'll look into this next quarter. We have seen some problems from module-info files in third-party jars, since they're Java 9 .class files and not everyone uses Java 9 yet. So, if we can get away with Automatic-Module-Name, we'll continue to do so, possibly even beyond next quarter. But if there are cases in which Automatic-Module-Name isn't good enough, that would be good to know.

@hrchu
Copy link
Author

@hrchu hrchu commented Oct 18, 2017

It is possible to only compile modile-info.java in Java 9, so the jar file is still compatible to users who uses earlier Java version.

A maven example:
https://github.com/twonote/radosgw-admin4j/blob/java9/pom.xml#L127

@cpovirk
Copy link
Member

@cpovirk cpovirk commented Oct 18, 2017

Right, thanks. We've seen problems even when the main .class files are compiled for an older version but the module-info.class is present. As I understand it, various tools try to process all .class files, and they need to be updated to ignore module-info.class.

@hrchu
Copy link
Author

@hrchu hrchu commented Oct 19, 2017

@cpovirk could you tell me more about this problem?

@cpovirk
Copy link
Member

@cpovirk cpovirk commented Oct 19, 2017

I wasn't personally involved in fixing the problems, but the basic idea seems to be that people scan the whole classpath (using something like ClassPath.getTopLevelClasses -- which might be an example of something that needs updated to ignore module-info.class :)) and then try to examine/load the classes with a tool that understands only, say, Java 8.

@orionll
Copy link

@orionll orionll commented Feb 20, 2018

It's worth mentioning that if we add module-info.java, all packages will not be open anymore.

@jbduncan
Copy link
Contributor

@jbduncan jbduncan commented Feb 20, 2018

@orionll Am I right to think/remember that in the JPMS, open packages are packages whose internal classes can be inspected with reflection?

@orionll
Copy link

@orionll orionll commented Feb 20, 2018

@jbduncat Yes, exactly. And also private members of public classes.

@jbduncan
Copy link
Contributor

@jbduncan jbduncan commented Feb 20, 2018

@orionll Cool, thanks for confirming things for me. :)

I personally wonder how important it would be for Guava's packages to be open when used on the module path. I struggle to imagine that reflectively calling Guava's internals is a common thing to do, especially considering Guava's (IMO) pretty durn good API. 🤔

@HoldYourWaffle
Copy link

@HoldYourWaffle HoldYourWaffle commented Feb 20, 2018

Are there any reasons for it not being open? Even if it's uncommon it might still be done by some people.

@jbduncan
Copy link
Contributor

@jbduncan jbduncan commented Feb 20, 2018

@HoldYourWaffle I think the main reason is it prevents people from using reflection to depend on internals which may change or disappear in future releases of Guava without warning.

@jbduncan
Copy link
Contributor

@jbduncan jbduncan commented Feb 20, 2018

...which by my understanding makes things easier for everyone in the long-run.

@jbduncan
Copy link
Contributor

@jbduncan jbduncan commented Feb 20, 2018

The only reason I can currently think of to have Guava's packages open in the module-info.java is if frameworks like Spring need to reflectively access its internals to do important stuff, but I don't know how important or common that is.

@orionll
Copy link

@orionll orionll commented Feb 20, 2018

All Guava packages should be closed because as @jbduncan said the dependence on class internals is a bad practice. If someone really wants to access the internals, they can use --add-opens command line option which forces the specified package to be open.

@HoldYourWaffle
Copy link

@HoldYourWaffle HoldYourWaffle commented Feb 20, 2018

Good point I forgot about --add-opens. Imho you should always be able to hack into internals (maybe you want to do something the developers didn't think of but it's too 'personal' that it's not worthy of a PR), with the risk of it breaking in new versions. --add-opens allows for this so it'd indeed be better to close the guava packages.

@SamCarlberg
Copy link

@SamCarlberg SamCarlberg commented Aug 17, 2018

Guava has an Automatic-Module-Name in its MANIFEST.MF now, so I believe this is not quite as important as it may seem. But if I'm mistaken, then I'd be more than happy to be proven wrong.

It does mean that jlink will not work, since the tool requires a module name to be specified in the module-info.java file; automatic module names will not be accepted.

@hannes-transentials
Copy link

@hannes-transentials hannes-transentials commented Dec 9, 2018

As much as I love Guava and appreciate Google's efforts, it is somehow embarrassing that a company like Google is not able to adopt Java modules within one year.

Either Google does not use Guava internally or they keep using JDK 8 and won't adopt Jigsaw.

@jbduncan
Copy link
Contributor

@jbduncan jbduncan commented Dec 9, 2018

@hannes-transentials I think it's most likely that Google have not migrated to JDK 11 and adopted modules yet simply because their internal codebase is so mind-bogglingly humongous. ;)

I say this because I remember reading somewhere (or I inferred) that they use Guava or an superset internally, and I also remember they announced a few years ago that they'd finally migrated to JDK 8 after a lot of effort. So I'm sure that they'll announce support for JDK 11 or a later LTS version (and, by extension, modules) when they fully migrate away from Java 8 and when they feel that most of us non-Googlers have moved away from Java 8 too. (I know that my company hasn't done so yet simply because Java 9 was such a freaking big, backwards-incompatible change!)

@orionll
Copy link

@orionll orionll commented Dec 9, 2018

It's worth mentioning that adding module-info.java can break some existing tools. For example, I know that IDEA's Osmorc plugin does not work when both module-info.java exists and the library is an OSGi bundle (Guava is). So, while the tools are not ready yet, I would abstain from adding module-info.java to Guava.

@hannes-transentials
Copy link

@hannes-transentials hannes-transentials commented Dec 9, 2018

So I either do without modularized applications or stay away from Guava (and many other popular applications)? I somehow hoped that there was some middle ground.

@jbduncan
Copy link
Contributor

@jbduncan jbduncan commented Dec 9, 2018

Well... you can use Guava as a module in a vanilla-Java modular application. But since Guava only includes an Automatic-Module-Name in its manifest, rather than going further and including amodule.info (out of necessity to stay Java-8-compatible), you won't be able to use it with jlink to create minimised modular Java applications.

Furthermore, frameworks built on top of Java that have their own programming models, like Spring, may have not fully migrated to be Java-11-compatible yet, so if you use such frameworks a lot, you may have to wait a bit longer.

That being said, if you do use a framework such a Spring, please check for yourself if Java 11 and modules work with it, since my knowledge of Spring and other frameworks is limited. :)

@overheadhunter
Copy link

@overheadhunter overheadhunter commented Dec 10, 2018

out of necessity to stay Java-8-compatible

Well you can create multi-release jars, where the module-info.class file only gets included inside META-INF/versions/9 and is therefore invisible for old¹ class loaders.


¹ As long as no fancy custom class loaders eagerly load everything they find in a jar without reading the manifest entries.

@talios
Copy link

@talios talios commented Dec 11, 2018

@hannes-transentials You could make use of something like https://github.com/moditect/moditect to adapt guava and add a module-info.java/.class at your applications side of things as a transitionary work around.

If module-info.java was to be added to guava, hopefully it'd be done so as a modular jar so we don't break java 8< versions.

@seinecle
Copy link

@seinecle seinecle commented May 11, 2020

So Guava is still not natively JPMS compatible in May 2020?

@cowwoc
Copy link

@cowwoc cowwoc commented May 11, 2020

No. And it isn't hard to add support without breaking pre-Java9 support. As @overheadhunter mentioned, all they need to do is add META-INF/versions/9/module-info.class (multi-release JAR) and it would be compatible with both versions.

The easiest way to provide Java9 support is to release a separate artifact for it but if they don't want to maintain multiple artifacts then the multi-release JAR approach would work as well (it's just harder to build).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.