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 an Automatic-Module-Name manifest entry #2846

Closed
wants to merge 2 commits into
base: master
from

Conversation

Projects
None yet
7 participants
@eljobe
Contributor

eljobe commented Jun 15, 2017

This is recommended for any java library which is being published to
repositories like MavenCentral or JCenter to ensure that when you do
eventually convert the library to a Java 9 module, it won't change
names requiring all of your consumers and the projects which depend
upon your consumers to update their moudle-info.java files to
pick up the new name.

We can debate whether or not com.google.guava is the name you want
to adopt for your module. Other possible candidates are:

  • guava
  • google.guava
  • com.google.common.guava
  • Something else

This article covers
a lot of the reasons you might want to use com.google.guava, but I have also read reasonable arguments for more concise names if you aren't worried about module name conflicts.

Related (a little bit) to #2571

@googlebot googlebot added the cla: yes label Jun 15, 2017

@Stephan202

This comment has been minimized.

Show comment
Hide comment
@Stephan202

Stephan202 Jun 15, 2017

@jodastephen, the author of that article, actually strongly suggests using com.google.common.

Stephan202 commented Jun 15, 2017

@jodastephen, the author of that article, actually strongly suggests using com.google.common.

@eljobe

This comment has been minimized.

Show comment
Hide comment
@eljobe

eljobe Jun 15, 2017

Contributor

@Stephan202 you are right. I am happy to change the module name in the pull request to com.google.common if the Guava project owns that entire package namespace. I was under the (quite possibly wrong) impression that other libraries provided by other teams at Google might also contribute to that package namespace, and as such, thought that we should coordinate with other libraries/modules that provided subpackages of com.google.common by naming this module com.google.common.guava. I agree that it would be better to use the root package of the whole package hierarchy.

But, first I would like someone to be able to confidently confirm, "No other jar files inside or outside Google contribute classes to the com.google.commons package. It is entirely dedicated to the guava project."

If that's the case, I'll update the pull request on getting that confirmation.

Contributor

eljobe commented Jun 15, 2017

@Stephan202 you are right. I am happy to change the module name in the pull request to com.google.common if the Guava project owns that entire package namespace. I was under the (quite possibly wrong) impression that other libraries provided by other teams at Google might also contribute to that package namespace, and as such, thought that we should coordinate with other libraries/modules that provided subpackages of com.google.common by naming this module com.google.common.guava. I agree that it would be better to use the root package of the whole package hierarchy.

But, first I would like someone to be able to confidently confirm, "No other jar files inside or outside Google contribute classes to the com.google.commons package. It is entirely dedicated to the guava project."

If that's the case, I'll update the pull request on getting that confirmation.

@cpovirk

This comment has been minimized.

Show comment
Hide comment
@cpovirk

cpovirk Jun 16, 2017

Member

We do release other things under com.google.common, but in the discussion linked by @Stephan202, we're told that's not a problem for using that module name.

Member

cpovirk commented Jun 16, 2017

We do release other things under com.google.common, but in the discussion linked by @Stephan202, we're told that's not a problem for using that module name.

@eljobe

This comment has been minimized.

Show comment
Hide comment
@eljobe

eljobe Jun 16, 2017

Contributor

It's true. As long as you're willing to claim that the package root com.google.common is owned by the guava team, it's a fine choice. I've updated the pull request to match.

Contributor

eljobe commented Jun 16, 2017

It's true. As long as you're willing to claim that the package root com.google.common is owned by the guava team, it's a fine choice. I've updated the pull request to match.

@jbduncan

This comment has been minimized.

Show comment
Hide comment
@jbduncan

jbduncan Jun 16, 2017

Contributor

@cpovirk Does the Guava project wholly own the com.google.common package and it's sub-packages, both externally on GitHub and internally within Google?

@eljobe If the Guava project does not wholly own com.google.common and/or it's sub-packages, will this be a problem?

Contributor

jbduncan commented Jun 16, 2017

@cpovirk Does the Guava project wholly own the com.google.common package and it's sub-packages, both externally on GitHub and internally within Google?

@eljobe If the Guava project does not wholly own com.google.common and/or it's sub-packages, will this be a problem?

@jbduncan

This comment has been minimized.

Show comment
Hide comment
@jbduncan

jbduncan Jun 16, 2017

Contributor

Hmm, after re-reading this conversation, I understand now that only the com.google.common package needs to be owned by the Guava team?

On the assumption that my new understanding is correct, I'll rephrase my previous questions:

  1. Does the Guava project wholly own the com.google.common package (not necessarily it's sub-packages)?
  2. If com.google.common isn't wholly owned by Guava, would this be a problem for migrating to modules?
Contributor

jbduncan commented Jun 16, 2017

Hmm, after re-reading this conversation, I understand now that only the com.google.common package needs to be owned by the Guava team?

On the assumption that my new understanding is correct, I'll rephrase my previous questions:

  1. Does the Guava project wholly own the com.google.common package (not necessarily it's sub-packages)?
  2. If com.google.common isn't wholly owned by Guava, would this be a problem for migrating to modules?
@eljobe

This comment has been minimized.

Show comment
Hide comment
@eljobe

eljobe Jun 16, 2017

Contributor

I think I may be introducing more confusion than clarity here, but it's worth writing about in a bit more detail because we really only want to make this decision once.

First of all, I think that Stephen makes a well-reasoned argument in his JPMS module naming post.

The point about com.google.common not being wholly "owned" by the Guava team is why I originally proposed that we deviate from Stephen's suggestion and go with com.google.guava instead of com.google.common. The scenario we want to avoid is this one in the future.

There is are 3 separate and mostly-independent teams inside Google each of which maintains a module which exports some packages in the com.google.common namespace. Let's call the teams (the people):
Guava Team
Blue Team
Red Team

Guava Team publishes a module which exports packages (reduced for space):

  • com.google.common.annotations
  • com.google.common.base
  • com.google.common.collect

Blue Team publishes a module which exports packages:

  • com.google.common.bonnet
  • com.google.common.bird
  • com.google.common.sky

Red Team publishes a module which exports packages:

  • com.google.common.head
  • com.google.common.hydrant
  • com.google.common.robin

Only one of those teams can call their module com.google.common. If the Guava Team takes that, then what will the Blue Team and Red Team use? I'm assuming here that we don't really want the package structure to reflect organizational structure. It should represent what the code in the packages actually does. So, we don't want to force rerooting packages like com.google.guava.common.base or com.google.blue.common.bird just to create artificial common prefixes we can use for the module names.

There isn't really a great answer here. Personally, I think that google.guava would be a fine name. And google.blue and google.red may eventually make sense for the other modules once they are written. Modules (like the jars in which they are packaged) typically are the natural responsibility of a team of people. Package names are about the organizational logic of the code, but module names can (and maybe even should) reflect the group that is responsible for the module's maintenance. Suppose the Guava project grows in such a way that it makes sense to deliver a separate module for all of the "collect" and "base" packages separate from all the other packages currently bundled in the library. Which of the modules retains the name "com.google.common"? I think it would make more sense at that point to announce to the community that the "google.guava" module is jettisoning the "collect" and "base" packages into a new "google.guava.core" or maybe "google.guava-core" or maybe even "google.lychee" module.

I actually think it might be better to separate the module names from the packages they contain because those concepts evolve through separate development lifecycles.

But, ultimately, I care less about the name you choose, than that you choose it before the 23.0 release, so we can get it published with this new manifest attribute. The choice is your's.

Contributor

eljobe commented Jun 16, 2017

I think I may be introducing more confusion than clarity here, but it's worth writing about in a bit more detail because we really only want to make this decision once.

First of all, I think that Stephen makes a well-reasoned argument in his JPMS module naming post.

The point about com.google.common not being wholly "owned" by the Guava team is why I originally proposed that we deviate from Stephen's suggestion and go with com.google.guava instead of com.google.common. The scenario we want to avoid is this one in the future.

There is are 3 separate and mostly-independent teams inside Google each of which maintains a module which exports some packages in the com.google.common namespace. Let's call the teams (the people):
Guava Team
Blue Team
Red Team

Guava Team publishes a module which exports packages (reduced for space):

  • com.google.common.annotations
  • com.google.common.base
  • com.google.common.collect

Blue Team publishes a module which exports packages:

  • com.google.common.bonnet
  • com.google.common.bird
  • com.google.common.sky

Red Team publishes a module which exports packages:

  • com.google.common.head
  • com.google.common.hydrant
  • com.google.common.robin

Only one of those teams can call their module com.google.common. If the Guava Team takes that, then what will the Blue Team and Red Team use? I'm assuming here that we don't really want the package structure to reflect organizational structure. It should represent what the code in the packages actually does. So, we don't want to force rerooting packages like com.google.guava.common.base or com.google.blue.common.bird just to create artificial common prefixes we can use for the module names.

There isn't really a great answer here. Personally, I think that google.guava would be a fine name. And google.blue and google.red may eventually make sense for the other modules once they are written. Modules (like the jars in which they are packaged) typically are the natural responsibility of a team of people. Package names are about the organizational logic of the code, but module names can (and maybe even should) reflect the group that is responsible for the module's maintenance. Suppose the Guava project grows in such a way that it makes sense to deliver a separate module for all of the "collect" and "base" packages separate from all the other packages currently bundled in the library. Which of the modules retains the name "com.google.common"? I think it would make more sense at that point to announce to the community that the "google.guava" module is jettisoning the "collect" and "base" packages into a new "google.guava.core" or maybe "google.guava-core" or maybe even "google.lychee" module.

I actually think it might be better to separate the module names from the packages they contain because those concepts evolve through separate development lifecycles.

But, ultimately, I care less about the name you choose, than that you choose it before the 23.0 release, so we can get it published with this new manifest attribute. The choice is your's.

eljobe added some commits Jun 15, 2017

Add an Automatic-Module-Name manifest entry
This is recommended for any java library which is being published to
repositories like MavenCentral or JCenter to ensure that when you do
eventually convert the library to a Java 9 module, it won't change
names requiring all of your consumers and the projects which depend
upon your consumers to update their `moudle-info.java` files to
pick up the new name.

We can debate whether or not `com.google.guava` is the name you want
to adopt for your module. Other possible candidates are:
 * `guava`
 * `google.guava`
 * `com.google.commons.guava`
 * Something else

[This
article](http://blog.joda.org/2017/05/java-se-9-jpms-automatic-modules.html)
covers a lot of the reasons you might want to use `com.google.guava`,
but I have also read reasonable arguments for more concice names if
you aren't worried about module name conflicts.

Related (a little bit) to #2571
Change to com.google.common
The Guava team has decided to take responsiblity that all modules
under this namespace have unique module names. This is based
largely on reccommendations in this
[email thread](https://groups.google.com/forum/#!msg/guava-discuss/1I--H7xwwR8/OLvJo-FhAwAJ).
@jodastephen

This comment has been minimized.

Show comment
Hide comment
@jodastephen

jodastephen Jun 20, 2017

Contributor

Lets start by observing that Google (the company) owns everything under com.google. As such, it can choose to structure module names under there any way it wants, so long as there is a company-wide co-ordination to ensure that no package appears in two modules. This observation allows many choices for the module name however, and as such isn't that helpful.

(The observation is however that ALL Google modules should start with com.google, so I'd object strongly to google.guava as your module name).

The next observation is that the standard (Java-wide) rule for module names should be that the module name is the super-package name of the project. While this rule handles many cases, it does not of course handle the Guava case, as each package is a sibling.

In my blog, I describe this case, and argue that the implied super-package in a case like this is the next level up. Thus, I arrive at my view of com.google.common being the right package name for Guava. Doing so does not stop other teams using com.google.common.bird or com.google.common.head as module names if they need to.


Looking to the future, there is another way to view the whole problem space however. Each package in Guava is pretty isolated. There are dependencies between the packages, but they form a DAG as far as I can tell. As such, it would be perfectly possible for each package to be a separate module (where the module name is then obviously the package name).

Now, today this would be a pain to do, because it would mean publishing a separate artifact to Maven Central for each package, something that nobody would really want. However, there is a fair chance that Oracle will consider having multi-module jar files in a future release of Java (ie. one jar file containing many modules). Were this to happen, having a module for each package is suddenly not such a bad idea, as users could then depend on the subset of Guava they care about, or the whole of it, and not suffer any clashes.

In this scenario, the Guava module would then be an aggregating module that contains no bytecode of its own:

module ???? {
  requires transitive com.google.common.annotations;
  requires transitive com.google.common.base;
  requires transitive com.google.common.collect;
}

This is similar to the JDK, where the java.se module aggregates others. But note that there is no java.se package. ie. Aggregating modules can and will have names that differ from the packages, because they necessarily are aggregations of disconnected packages for the purpose of convenience.

Given this world view, com.google.guava is a viable module name, because the "Guava" project can be thought of as an aggregation of a set of unrelated packages Google chooses to publish publicly.

One final note however, if com.google.guava were chosen, Google the company would be committing to never having a package name of com.google.guava, as to do so would be asking for trouble.


So, either com.google.common or com.google.guava are reasonable choices derived through different thought processes. While I originally strongly recommended the former, the latter does now have appeal given the description above of internal teams also wanting to use the com.google.common module name.

Ultimately, the Guava team must decide as to which of the two world-views of the project describes it best - a single project formed of a coherent set of packages (com.google.common). Or an aggregation of relatively separate packages that could standalone, unified under a brand name (com.google.guava).

Contributor

jodastephen commented Jun 20, 2017

Lets start by observing that Google (the company) owns everything under com.google. As such, it can choose to structure module names under there any way it wants, so long as there is a company-wide co-ordination to ensure that no package appears in two modules. This observation allows many choices for the module name however, and as such isn't that helpful.

(The observation is however that ALL Google modules should start with com.google, so I'd object strongly to google.guava as your module name).

The next observation is that the standard (Java-wide) rule for module names should be that the module name is the super-package name of the project. While this rule handles many cases, it does not of course handle the Guava case, as each package is a sibling.

In my blog, I describe this case, and argue that the implied super-package in a case like this is the next level up. Thus, I arrive at my view of com.google.common being the right package name for Guava. Doing so does not stop other teams using com.google.common.bird or com.google.common.head as module names if they need to.


Looking to the future, there is another way to view the whole problem space however. Each package in Guava is pretty isolated. There are dependencies between the packages, but they form a DAG as far as I can tell. As such, it would be perfectly possible for each package to be a separate module (where the module name is then obviously the package name).

Now, today this would be a pain to do, because it would mean publishing a separate artifact to Maven Central for each package, something that nobody would really want. However, there is a fair chance that Oracle will consider having multi-module jar files in a future release of Java (ie. one jar file containing many modules). Were this to happen, having a module for each package is suddenly not such a bad idea, as users could then depend on the subset of Guava they care about, or the whole of it, and not suffer any clashes.

In this scenario, the Guava module would then be an aggregating module that contains no bytecode of its own:

module ???? {
  requires transitive com.google.common.annotations;
  requires transitive com.google.common.base;
  requires transitive com.google.common.collect;
}

This is similar to the JDK, where the java.se module aggregates others. But note that there is no java.se package. ie. Aggregating modules can and will have names that differ from the packages, because they necessarily are aggregations of disconnected packages for the purpose of convenience.

Given this world view, com.google.guava is a viable module name, because the "Guava" project can be thought of as an aggregation of a set of unrelated packages Google chooses to publish publicly.

One final note however, if com.google.guava were chosen, Google the company would be committing to never having a package name of com.google.guava, as to do so would be asking for trouble.


So, either com.google.common or com.google.guava are reasonable choices derived through different thought processes. While I originally strongly recommended the former, the latter does now have appeal given the description above of internal teams also wanting to use the com.google.common module name.

Ultimately, the Guava team must decide as to which of the two world-views of the project describes it best - a single project formed of a coherent set of packages (com.google.common). Or an aggregation of relatively separate packages that could standalone, unified under a brand name (com.google.guava).

@eljobe

This comment has been minimized.

Show comment
Hide comment
@eljobe

eljobe Jul 1, 2017

Contributor

What is the process by which the guava team can get this decision made?

Contributor

eljobe commented Jul 1, 2017

What is the process by which the guava team can get this decision made?

@kluever

This comment has been minimized.

Show comment
Hide comment
@kluever

kluever Jul 6, 2017

Member

As @kevinb9n said here,

Provisionally, the name com.google.common seems fine.

Member

kluever commented Jul 6, 2017

As @kevinb9n said here,

Provisionally, the name com.google.common seems fine.

@cpovirk

This comment has been minimized.

Show comment
Hide comment
@cpovirk

cpovirk Jul 6, 2017

Member

@jodastephen's recommendation was simply to declare which module name we choose. (And I think we're all happy with com.google.common.) He hadn't recommended specifically to us that we set Automatic-Module-Name, but his later blog post sounds to me like it recommends the practice in general. Stephen -- just to check explicitly -- do you recommend that we set Automatic-Module-Name? Is there any downside, given that we're happy with com.google.common?

Member

cpovirk commented Jul 6, 2017

@jodastephen's recommendation was simply to declare which module name we choose. (And I think we're all happy with com.google.common.) He hadn't recommended specifically to us that we set Automatic-Module-Name, but his later blog post sounds to me like it recommends the practice in general. Stephen -- just to check explicitly -- do you recommend that we set Automatic-Module-Name? Is there any downside, given that we're happy with com.google.common?

@jodastephen

This comment has been minimized.

Show comment
Hide comment
@jodastephen

jodastephen Jul 6, 2017

Contributor

Now that JDK 9 looks like passing the official processes with no further changes, it is safe (and recommended) to add Automatic-Module-Name to Guava.

You'll keep declaring that until you write a proper module-info file, which won't be too hard to do once JDK 9 is finally released. (Maven has support for compiling module-info.java on JDK 9 and merging the .class file with the rest of the code so it all works on JDK 8).

Contributor

jodastephen commented Jul 6, 2017

Now that JDK 9 looks like passing the official processes with no further changes, it is safe (and recommended) to add Automatic-Module-Name to Guava.

You'll keep declaring that until you write a proper module-info file, which won't be too hard to do once JDK 9 is finally released. (Maven has support for compiling module-info.java on JDK 9 and merging the .class file with the rest of the code so it all works on JDK 8).

@cpovirk

This comment has been minimized.

Show comment
Hide comment
@cpovirk

cpovirk Jul 6, 2017

Member

Thanks.

I'll get this submitted internally and then mirror it out.

Member

cpovirk commented Jul 6, 2017

Thanks.

I'll get this submitted internally and then mirror it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment