Hi Nicolai,
let's consider that my project depends on the following dependencies:
com.foo.bar:library:1.0 and com.acme:library:2.3.1, both unnamed.
I somehow want to have them both as requirements:
module M.N {
requires static library; // com.foo.bar:library
requires library; // com.acme:library
}
How can I define that the 'requires static library' should be mapped to
com.foo.bar:library:1.0 on the modulepath, while 'requires library' should
be mapped to com.acme:library:2.3.1
One ugly solution would be:
requires static library containing com.foo.bar.baz.SomeClass;
requires library containing acme.AnotherClass;
We should really wonder if ease-of-transition is worth the minefield we're
creating with the introduction of automodules. IMHO all options we're
trying to add to keep automodules will only over-complicate things, not
even being sure if all edges are covered.
thanks,
Robert
On Thu, 02 Feb 2017 12:28:13 +0100, Nicolai Parlog <n...@codefx.org> wrote:
Hi everyone,
after thinking about this a little longer, I came to the conclusion that
compile-time/launch-time aliasing might be the only way out of this (at
least the only I could come up with) that keeps automatic modules alive
and does not introduce a conceptual dependency on Maven.
The idea:
A command line option, let's say `--alias-modules A=X`, maps module name
A to module name X. Every dependency on either A or X will be resolved
to X, implying that there must a module X in the universe of observable
modules. There can be several aliases for the same module
(`--alias-modules A=X,B=X`; X needs to be observable) and they can be
chained (`--alias-modules A=X,X=Y`; Y needs to be observable)
Aliasing would of course have to be applied to qualified exports, opens,
and similar mechanisms as well.
It might be worth adding the rule that no observable module must have an
aliased name. So for `--alias-modules A=X` there must be no observable
module A. This prevents ambiguity and would effectively prevent aliasing
platform modules. That might be a good thing because it looks like
aliasing and upgrading modules has quite some overlap (or is even
identical?)
Unfortunately I could not come up with a way to limit aliasing to
automatic module names (in case that were desirable) without somehow
marking dependencies on automatic modules, likely in the module
declaration. If changing module declaration syntax is still on the
table, it could be changed so that dependencies on automatic modules
must be phrased as something like `requires automatic`.
The obvious semantics would be that only such requires clauses can be
fulfilled with automatic modules and that only such dependencies could
be aliased (this might make it prudent to phrase the aliasing option
accordingly, e.g. `--alias-automatic-modules`).
This could also be used to help developers in keeping their module
declarations clean: The compiler could to emit a warning if a `requires
automatic` clause is fulfilled by a regular module.
I would love to hear some thoughts on this idea, even if it considered
to be stupid, impractical,etc. :)
so long ... Nicolai
On 27.01.2017 15:11, Stephen Colebourne wrote:
Back in October, I raised the issue of modules names generally and for
automatic modules specifically [1]. The short thread came to no
conclusion, but recent threads have again raised similar problems. The
problem is that automatic modules have magical name creation from a
filename, which is brittle and unlike anything else in Java.
I also recently looked at the Joda-Convert and Joda-Beans libraries,
to see if I could add module-info in preparation for Java 9. I quickly
backed away, again because of the same issue. Put simply, I am
unwilling to write a module-info file that refers to a dependency that
is not yet a module. And I have to advise all open source projects to
do the same. Given this, there can be no simple migration to the JPMS
for open source projects. Each open source project must wait for all
its dependencies to migrate to JPMS (by adding a module-info and
publishing to Maven Central).
The issue is clear. If I write this:
module org.joda.convert {
requires guava;
}
where guava is an automatic module, I am locking in the name of the
guava dependency, something that I do not control. The name "guava" is
just a guess. The guava authors might choose "com.google.guava" or
something else entirely.
In a closed system of modules, ie. a private application, automatic
modules are fine, because the requires clause can be changed if it
turns out the guess was wrong. But once published as an open source
project to Maven Central or elsewhere, the guess cannot be fixed if it
is wrong (without releasing a new version of the library, which is not
an acceptable solution).
I also strongly believe that module names cannot be flat and
unstructured, such as "joda-convert" or "guava". They must have
structure, such as the domain name or a Maven-style group name
"org.joda.convert" or "org.joda:joda-convert". The potential for
clashes has been shown by the Maven team [2].
Some brainstormed possible changes:
- Remove the automatic module concept altogether
- Define a clear mapping from Maven Central co-ordinates to module
name that includes the group, artifact and classifier
- Provide a text file to JPMS that allows incorrect module names to be
mapped to the correct name
- Publicly advise against using automatic modules for open source
projects
- Change rules of Maven Central to prevent modular jars being added
that depend on an automatic module
- Allow requires clauses to have aliases - requires org.guava.guava OR
guava.
- Allow modules to have aliases - module org.guava.guava AKA guava
Given that applications can depend on libraries that haven't been
released in years, this has the potential to be a critical problem for
the ecosystem. My preference remains to define a clear mapping from
the widely adopted Maven Central naming strategy to JPMS modules.
Ideally, this would be a formal group concept in the JPMS, something
that I believe is sorely lacking.
Stephen
[1]
http://mail.openjdk.java.net/pipermail/jigsaw-dev/2016-October/009631.html
[2]
http://mail.openjdk.java.net/pipermail/jpms-spec-observers/2017-January/000707.html