On 11/3/2015 1:56 AM, Jochen Theodorou wrote:
On 02.11.2015 22:03, Alex Buckley wrote:
For groovy.util the case is more problematic. Moving GroovyTestCase into
a new package would for example break an estimated 95% of our test
cases. What will most likely happen is, that the test module merges with
the base module thus pulling in "optional" dependencies like JUnit 3...
which is in conflict with us trying to slim down the base runtime even
more, to for example give the android version an easier standing. We
have been thinking about for example moving the compiler into a separate
jar. But splitting something something as tightly coupled as that will
cause numerous same-package conflicts... Just to give an example... Eval
is a class in groovy.util and used for example like this:
assert 10 == Eval.me(' 2 * 4 + 2')
assert 10 == Eval.x(2, ' x * 4 + 2')
Of course this will call the compiler.. but what use is there to make a
groovy-base and a groovy compiler jigsaw style module, if they strongly
depend on each other anyway?
groovy-compiler will obviously have a hard dependency on groovy-base,
but you can avoid groovy-base having a hard dependency on
groovy-compiler by using services. Of course this assumes a suitable
split between the interface of your compiler and its implementation.
Even the java.base module is very open to external providers -- see the
Services column of
http://cr.openjdk.java.net/~mr/jigsaw/ea/module-summary.html#java.base
-- for example, "uses java.net.ContentHandlerFactory" can be provided by
java.desktop, and "uses java.security.Provider" can be provided by
java.naming, java.security.jgss, et al.
Anyway... my intension was to give an example of how some people divide
a broad library into "modules" and how it does not fit the "one module
per jar, no exported name space duplication" idea. And you just
confirmed it with the initial modularization of JavaFX.
Yes. We were clear at JavaOne that 1:1 migration -- one module per JAR
-- is just one possibility among many. I actually expect the main
obstacle to 1:1 migration to be not duplication of exported packages but
rather cycles between classes in the JARs.
also... there is a automated meta class lookup system, that is based on
the package name with a prefix. So someone could provide a meta class
for java.util.ArrayList, while another does this for LinkedList. If they
are using modules, they cannot be loaded at the same time. Granted, I
don't like this mechanism, and I am looking for ways to deprecate it in
the near future, but it is another example of same-package conflicts.
Does this mean a Groovy meta class can currently be defined as a class
in the java.* run-time package of the bootstrap loader?
The class would be groovy.runtime.metaclass.java.util.ArrayListMetaClass
and doesn't have need the bootsrap loader for this of course. We
actually always avoided implementing logic that depends on being in the
bootstrap loader.
That's good. Still, as you said, the meta classes for java.util.{A,B}
might live in different modules, so each of those modules will try to
export g.r.m.java.util to the same consumer.
One option for the Groovy runtime is to special case its meta class
package hierarchy by arranging for g.r.m.** classes to be defined by,
and exported from, a special module that the runtime generates; the
runtime would set up readability between this module and the user
modules that "thought" they were defining and exporting g.r.m.**.
You can see a flavor of this technique in the "dynamic module" created
by Java's Core Reflection when you proxy certain interfaces -- see
"Package and Module Membership of Proxy Class" in
http://cr.openjdk.java.net/~mr/jigsaw/spec/api/java/lang/reflect/Proxy.html.
Alex