Avoiding same-package conflicts
Alex Buckley
alex.buckley at oracle.com
Tue Nov 3 21:28:29 UTC 2015
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
More information about the jigsaw-dev
mailing list