Re: Avoiding same-package conflicts

2015-11-06 Thread Jochen Theodorou

On 03.11.2015 22:28, Alex Buckley wrote:
[...]

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.


and of course that split does not exist ;) It is a difference of not 
including something and referring to it by reflection, to have it 
optional; and to have it as a service. The first we can do without 
bigger changes, the later requires the definition of a whole "new" API.


[...]

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.


will have a look soon, thanks.

bye Jochen



Re: Avoiding same-package conflicts

2015-11-04 Thread Alan Bateman


On 04/11/2015 07:45, Jeroen Frijters wrote:

:
In your JavaOne talk you also mentioned "[no] duplication of exported packages", but the 
real restriction (at least in the current builds) seems to be "no duplication of packages (in 
the same layer)".

Can you confirm this?

Not quite, the requirement is that a module M cannot read two or modules 
that export the same package to M. This is one of the checks when 
creating a configuration:


http://cr.openjdk.java.net/~mr/jigsaw/spec/api/java/lang/module/Configuration.html#resolve-java.lang.module.ModuleFinder-java.lang.reflect.Layer-java.lang.module.ModuleFinder-java.util.Collection-

Instantiating a configuration as a Layer requires that you don't map two 
modules with the same package to the same class loader. More on this here:


http://cr.openjdk.java.net/~mr/jigsaw/spec/api/java/lang/reflect/Layer.html#create-java.lang.module.Configuration-java.lang.reflect.Layer.ClassLoaderFinder-

I think some of the chatter here has been specific to the boot layer 
where all modules on the application module path are mapped to the 
application class loader.


-Alan


RE: Avoiding same-package conflicts

2015-11-04 Thread Jeroen Frijters
Alex Buckley wrote:
> 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.

In your JavaOne talk you also mentioned "[no] duplication of exported 
packages", but the real restriction (at least in the current builds) seems to 
be "no duplication of packages (in the same layer)".

Can you confirm this?

Thanks,
Jeroen



Re: Avoiding same-package conflicts

2015-11-03 Thread Jochen Theodorou

On 02.11.2015 22:03, Alex Buckley wrote:
[...]

The initial modularization of JavaFX had a similar pattern: more split
packages than you would think, due to a "horizontal" module wanting to
share packages with numerous "vertical" domain modules. There, the
"horizontal" module was a 'builder' module which hoped to add
$COMPONENTBuilder classes to the packages of various 'component'
modules; eventually the $COMPONENTBuilder classes were deemed
unnecessary and the 'builder' module deleted. For Groovy, I suggest that
your "base module" has the greatest claim to the
org.codehaus.groovy.runtime package, and that the
groovy-{nio,sql,swing,xml} modules should export
org.codehaus.groovy.runtime.* subpackages to the base module only.

It doesn't seem great that the groovy-ant and groovy-test modules try to
augment the important groovy.util package owned by your base module.
Speaking generally, it makes no sense to allow a module to protect its
internals if at the same time its API can be augmented by unrelated
modules -- it can't be the "same" API because it doesn't have access to
the same internals.


Oh, I am not talking about internal API here.

The conflicts in org.codehaus.groovy.runtime are due to historic 
reasons. They are mostly extension methods, which could be in any 
package. But traditionally they had been part of DefaultGroovyMethods, 
from which we factored out a lot of methods over time to modularize the 
codebase more. And they tended to stay in the same package, since there 
was in the past no reason to choose a different one... looks strange to 
put a single class in a package that could be somewhere else perfectly 
fine after all. If we move those classes to new packages, then we will 
get into trouble with static compiled code. After all we did that 
modularization before Groovy had an optional static compiler, and we did 
a major version change for that (from 1.8 to 2.0) as well.


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?


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.


Just to clarify... hiding parts of API is out of scope for groovy 
modules atm. A first step for us would be to get some kind of mapping of 
our current multi jar system to jigsaw modules that fits our needs.



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.


bye Jochen


Re: Avoiding same-package conflicts

2015-11-03 Thread Alex Buckley

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


Re: Avoiding same-package conflicts

2015-11-02 Thread Alex Buckley

On 10/30/2015 1:38 PM, Jochen Theodorou wrote:

I can second that by an example using Groovy. We have not yet taken
steps to make jigsaw modules, but we quite some time ago we have split
the code base in what would become eventually become modules in the
future. Because of history this did mean to split packages. So we have a
couple of jars (that want to be modules), with overlapping package names.

Examples of package conflicts with the "base module":

* The groovy-console has a conflict in groovy.ui
* groovy-ant has a conflict in groovy.util
* groovy-docgenerator in org.codehaus.groovy.tools
* groovy-nio in org.codehaus.groovy.runtime
* groovy-sql in org.codehaus.groovy.runtime
* groovy-swing in org.codehaus.groovy.runtime
* groovy-test in goovy.lang and groovy.util
* groovy-xml in org.codehaus.groovy.runtime and goovy.util

That's 7 "modules" with conflicts out of 19. One should remember here,
that the codebase is like 10+ years old, and something that is now a
"module" used to be fixed part of the language in the past. So some poor
naming decision have been made. The org.codehaus.groovy.runtime
conflicts could probably be solved, but the groovy.util ones are
difficult, since this is a package imported by default (like java.lang
in java), so moving classes to differing packages will break Groovy
scripts... very elementary here for example GroovyTestCase in
groovy-util, which is in the groovy-test "module"..


The initial modularization of JavaFX had a similar pattern: more split 
packages than you would think, due to a "horizontal" module wanting to 
share packages with numerous "vertical" domain modules. There, the 
"horizontal" module was a 'builder' module which hoped to add 
$COMPONENTBuilder classes to the packages of various 'component' 
modules; eventually the $COMPONENTBuilder classes were deemed 
unnecessary and the 'builder' module deleted. For Groovy, I suggest that 
your "base module" has the greatest claim to the 
org.codehaus.groovy.runtime package, and that the 
groovy-{nio,sql,swing,xml} modules should export 
org.codehaus.groovy.runtime.* subpackages to the base module only.


It doesn't seem great that the groovy-ant and groovy-test modules try to 
augment the important groovy.util package owned by your base module. 
Speaking generally, it makes no sense to allow a module to protect its 
internals if at the same time its API can be augmented by unrelated 
modules -- it can't be the "same" API because it doesn't have access to 
the same internals.



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?


Alex


Re: Avoiding same-package conflicts

2015-10-30 Thread Jochen Theodorou
I can second that by an example using Groovy. We have not yet taken 
steps to make jigsaw modules, but we quite some time ago we have split 
the code base in what would become eventually become modules in the 
future. Because of history this did mean to split packages. So we have a 
couple of jars (that want to be modules), with overlapping package names.


Examples of package conflicts with the "base module":

* The groovy-console has a conflict in groovy.ui
* groovy-ant has a conflict in groovy.util
* groovy-docgenerator in org.codehaus.groovy.tools
* groovy-nio in org.codehaus.groovy.runtime
* groovy-sql in org.codehaus.groovy.runtime
* groovy-swing in org.codehaus.groovy.runtime
* groovy-test in goovy.lang and groovy.util
* groovy-xml in org.codehaus.groovy.runtime and goovy.util

That's 7 "modules" with conflicts out of 19. One should remember here, 
that the codebase is like 10+ years old, and something that is now a 
"module" used to be fixed part of the language in the past. So some poor 
naming decision have been made. The org.codehaus.groovy.runtime 
conflicts could probably be solved, but the groovy.util ones are 
difficult, since this is a package imported by default (like java.lang 
in java), so moving classes to differing packages will break Groovy 
scripts... very elementary here for example GroovyTestCase in 
groovy-util, which is in the groovy-test "module"..


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.


bye Jochen

On 30.10.2015 12:28, Stephen Colebourne wrote:

On 29 October 2015 at 13:48, Alan Bateman  wrote:

The restriction is that no two modules with the same package (irrespective
of whether it is exported or not, or who reads the modules) can be mapped to
the same class loader.


FWIW, I think that this could be a headache for module adoption.

Here are three cases that appear to be troubled by these restrictions:

- a large project that has taken an existing project (module) and
split it in two. In order to preserve backwards compatibility, the
author wants to retain the package names. But doing so is not
possible, because a single package now needs to be split across two
modules.

- extending a package scoped API from another project. While hardly
pleasant this is sometimes the only viable approach to get a task
done. As an example, the ImmutableList class from Google Guava has a
package scoped constructor. It is perfectly possible today for an
application to write a class that extends ImmutableList, so long as
that class is placed in the com.google.common.collect package. The
module system has the potential to block this extension point. (I
imagine that cglib and similar tools also generate code in other
peoples modules)

- where a stable interface is copied into two separate jar files to
avoid a dependency. An example of this was commons-beanutils where 4
interfaces were copied from commons-collections. While this has now
been changed, it was considered useful at the time, and given the
stability of the interfaces in question, caused no problems.
https://issues.apache.org/jira/browse/BEANUTILS-379

FWIW, I'm most concerned about the first one going forward. However,
the other two are cases I've seen used, and if used broadly in the
wild could slow adoption (if it is hard to make those jar files
modular, and they are widely depended on).

Stephen





Re: Avoiding same-package conflicts

2015-10-30 Thread Stephen Colebourne
On 29 October 2015 at 13:48, Alan Bateman  wrote:
> The restriction is that no two modules with the same package (irrespective
> of whether it is exported or not, or who reads the modules) can be mapped to
> the same class loader.

FWIW, I think that this could be a headache for module adoption.

Here are three cases that appear to be troubled by these restrictions:

- a large project that has taken an existing project (module) and
split it in two. In order to preserve backwards compatibility, the
author wants to retain the package names. But doing so is not
possible, because a single package now needs to be split across two
modules.

- extending a package scoped API from another project. While hardly
pleasant this is sometimes the only viable approach to get a task
done. As an example, the ImmutableList class from Google Guava has a
package scoped constructor. It is perfectly possible today for an
application to write a class that extends ImmutableList, so long as
that class is placed in the com.google.common.collect package. The
module system has the potential to block this extension point. (I
imagine that cglib and similar tools also generate code in other
peoples modules)

- where a stable interface is copied into two separate jar files to
avoid a dependency. An example of this was commons-beanutils where 4
interfaces were copied from commons-collections. While this has now
been changed, it was considered useful at the time, and given the
stability of the interfaces in question, caused no problems.
https://issues.apache.org/jira/browse/BEANUTILS-379

FWIW, I'm most concerned about the first one going forward. However,
the other two are cases I've seen used, and if used broadly in the
wild could slow adoption (if it is hard to make those jar files
modular, and they are widely depended on).

Stephen


Re: Avoiding same-package conflicts

2015-10-30 Thread David M. Lloyd

On 10/30/2015 04:12 AM, Martin Lehmann wrote:

Hi David, hi all,

thanks, David, for your response.


Sure, reply is inline.


Full ACK. Bad practice.

I disagree, actually.  I think that this is a completely needless and 
artificial restriction that arose from implementation decisions, not from a 
valid requirement.

You have a point. I don't disagree ;-)


So we really need disjunct classes in *all* libraries now? Not even, if the redundant 
packages are not even exported (right?). Would it work in the "old" classpath?

I think that judging by whether something would work in an old classpath is a 
false test.


I see your point, but:
On the one hand: Migration will be a big issue. I followed the Monday JavaOne 
live streams talks (@Alan, @Alex: Thanks for the great talks!) on the topic and 
understood that stuff should work like before.
Well, ambitious enough, but if this is indeed the goal, then "did it work in the old 
classpath?" is definitely something to look at.
On the other hand - don't get me wrong: I personally prefer to have a clean and 
 proper solution without (too much) of bad design *just* because backward 
compatibility.


Sure, but only because you've reversed the logical sense of my argument: 
 I'm saying, don't limit what works under modules to what worked under 
classpath (i.e. using "well it never worked before" as a first-order 
justification for not allowing something to work under modules, or not 
caring that something doesn't work under modules).  You're saying, don't 
break things that previously worked on classpath.  In other words, we're 
not disagreeing, we're making two different points, and I agree with 
yours as well.



The whole point of modules is to throw off the restrictions and problems of the 
classpath, after all.  I think a better test is, "does this make sense?", and 
to use your slf4j example - it definitely makes sense, because:
...

Yep, agree.

Btw, I meanwhile thought of a second use case which will *definitely* be 
needed. Assume to use a third-party library where something is wrong. Fix is 
not (yet) available, so you need to fix something locally. Up to now a common 
though bad(?) practice is to patch the library class(es) locally and put it the 
patched class(es) on the classpath *before* the third-party library (... as a 
workaround until the real fix is there).

I doubt that I am the only one who ever had the need for such a workaround. If 
redundant packages are not longer allowed, then I (we?) need a replacement for 
such a scenario. (Or are I am now really expected to either encapsulate 
external stuff in different layers and/or to repackage external jar files to 
guarantee disjunct contents...?) Makes sense?


Under the JBoss Modules system, you typically drop your fixed JAR 
alongside the broken one in the module path, then update your module.xml 
file to point at the new one instead of the old one.  But this only 
works because module descriptors are external to the module in JBoss 
Modules.


--
- DML


RE: Avoiding same-package conflicts

2015-10-30 Thread Martin Lehmann
Hi David, hi all,

thanks, David, for your response.

>> Full ACK. Bad practice.
>I disagree, actually.  I think that this is a completely needless and 
>artificial restriction that arose from implementation decisions, not from a 
>valid requirement.
You have a point. I don't disagree ;-)

>> So we really need disjunct classes in *all* libraries now? Not even, if the 
>> redundant packages are not even exported (right?). Would it work in the 
>> "old" classpath?
> I think that judging by whether something would work in an old classpath is a 
> false test.  

I see your point, but:
On the one hand: Migration will be a big issue. I followed the Monday JavaOne 
live streams talks (@Alan, @Alex: Thanks for the great talks!) on the topic and 
understood that stuff should work like before. 
Well, ambitious enough, but if this is indeed the goal, then "did it work in 
the old classpath?" is definitely something to look at. 
On the other hand - don't get me wrong: I personally prefer to have a clean and 
 proper solution without (too much) of bad design *just* because backward 
compatibility.

> The whole point of modules is to throw off the restrictions and problems of 
> the classpath, after all.  I think a better test is, "does this make sense?", 
> and to use your slf4j example - it definitely makes sense, because:
> ...
Yep, agree.

Btw, I meanwhile thought of a second use case which will *definitely* be 
needed. Assume to use a third-party library where something is wrong. Fix is 
not (yet) available, so you need to fix something locally. Up to now a common 
though bad(?) practice is to patch the library class(es) locally and put it the 
patched class(es) on the classpath *before* the third-party library (... as a 
workaround until the real fix is there). 

I doubt that I am the only one who ever had the need for such a workaround. If 
redundant packages are not longer allowed, then I (we?) need a replacement for 
such a scenario. (Or are I am now really expected to either encapsulate 
external stuff in different layers and/or to repackage external jar files to 
guarantee disjunct contents...?) Makes sense?

Cheers,
Martin

-Original Message-
From: jigsaw-dev [mailto:jigsaw-dev-boun...@openjdk.java.net] On Behalf Of 
David M. Lloyd
Sent: Thursday, October 29, 2015 12:33 PM
To: jigsaw-dev@openjdk.java.net
Subject: Re: Avoiding same-package conflicts

On 10/29/2015 05:59 AM, Martin Lehmann wrote:
> Hi all,
>
> I stumbled across the same "issue".
>
>> that having multiple versions of the same library isn't a best practice to 
>> say the least.
> Full ACK. Bad practice.

I disagree, actually.  I think that this is a completely needless and 
artificial restriction that arose from implementation decisions, not 
from a valid requirement.

We have used our ability to ship multiple modules with the same package 
names to good effect on more than one occasion.  As long as a given 
module doesn't link the conflicting packages, there is no real problem. 
  Even hypothetical issues involving indirect linkage or passing objects 
back and forth have never really been a problem for us.

> I might have an (artifical?) use case where this might lead to some extra 
> effort in migration, though:
> Let's assume that two libraries D1 and D2 implement the same common API. For 
> some historical reason, both libraries *ship* the interfaces classes of that 
> common API.
> This won't work (easily) without repackaging jar files (even if the common 
> API classes would not even differ).
>
> Example:
> A --requires --> B, C
> B --requires --> D1
> C --requires --> D2
> D1 and D2 both contain the same interfaces. Even if neither B nor C would 
> *not* "requires public" D1 / D2, this would not work.
>
> Too artifical? I actually thought of two logging implementations using & 
> shipping the common slf4j interface classes.
>
> So we really need disjunct classes in *all* libraries now? Not even, if the 
> redundant packages are not even exported (right?). Would it work in the "old" 
> classpath?

I think that judging by whether something would work in an old classpath 
is a false test.  The whole point of modules is to throw off the 
restrictions and problems of the classpath, after all.  I think a better 
test is, "does this make sense?", and to use your slf4j example - it 
definitely makes sense, because:

* Modules generally use slf4j as a private API to perform their own 
logging functions
* Thus slf4j generally never leaks to a module's exported package set
* Thus there's no actual harm in allowing this, and much benefit - 
especially if B and C (in your example) are not completely under your 
control (which is inevitable in any nontrivial system)

-- 
- DML



Re: Avoiding same-package conflicts

2015-10-30 Thread Alan Bateman


On 30/10/2015 11:28, Stephen Colebourne wrote:

:

Here are three cases that appear to be troubled by these restrictions:

- a large project that has taken an existing project (module) and
split it in two. In order to preserve backwards compatibility, the
author wants to retain the package names. But doing so is not
possible, because a single package now needs to be split across two
modules.
The module system can facilitate many refactoring scenarios. This one 
seems an incompatible change. Even if the module system supported 
splitting a package between modules then it would force consumers of the 
original module to change their module dependences.




- extending a package scoped API from another project. While hardly
pleasant this is sometimes the only viable approach to get a task
done. As an example, the ImmutableList class from Google Guava has a
package scoped constructor. It is perfectly possible today for an
application to write a class that extends ImmutableList, so long as
that class is placed in the com.google.common.collect package. The
module system has the potential to block this extension point. (I
imagine that cglib and similar tools also generate code in other
peoples modules)
I assume if Guava wanted ImmutableList to be part of its API then it 
would have made it public. In any case, testing a package private class 
is a scenario that I can relate to. The -Xpatch option can help with 
that. In the intro slide deck then there is an example, it's the in 
"Director's cut", meaning the bonus slides after the presentation end slide.





- where a stable interface is copied into two separate jar files to
avoid a dependency. An example of this was commons-beanutils where 4
interfaces were copied from commons-collections. While this has now
been changed, it was considered useful at the time, and given the
stability of the interfaces in question, caused no problems.
https://issues.apache.org/jira/browse/BEANUTILS-379

Going forward then the ability to express dependences clearly should 
help avoid the need to do this kind of thing.


-Alan.



Re: Avoiding same-package conflicts

2015-10-29 Thread David M. Lloyd

On 10/29/2015 05:59 AM, Martin Lehmann wrote:

Hi all,

I stumbled across the same "issue".


that having multiple versions of the same library isn't a best practice to say 
the least.

Full ACK. Bad practice.


I disagree, actually.  I think that this is a completely needless and 
artificial restriction that arose from implementation decisions, not 
from a valid requirement.


We have used our ability to ship multiple modules with the same package 
names to good effect on more than one occasion.  As long as a given 
module doesn't link the conflicting packages, there is no real problem. 
 Even hypothetical issues involving indirect linkage or passing objects 
back and forth have never really been a problem for us.



I might have an (artifical?) use case where this might lead to some extra 
effort in migration, though:
Let's assume that two libraries D1 and D2 implement the same common API. For 
some historical reason, both libraries *ship* the interfaces classes of that 
common API.
This won't work (easily) without repackaging jar files (even if the common API 
classes would not even differ).

Example:
A --requires --> B, C
B --requires --> D1
C --requires --> D2
D1 and D2 both contain the same interfaces. Even if neither B nor C would *not* 
"requires public" D1 / D2, this would not work.

Too artifical? I actually thought of two logging implementations using & 
shipping the common slf4j interface classes.

So we really need disjunct classes in *all* libraries now? Not even, if the redundant 
packages are not even exported (right?). Would it work in the "old" classpath?


I think that judging by whether something would work in an old classpath 
is a false test.  The whole point of modules is to throw off the 
restrictions and problems of the classpath, after all.  I think a better 
test is, "does this make sense?", and to use your slf4j example - it 
definitely makes sense, because:


* Modules generally use slf4j as a private API to perform their own 
logging functions

* Thus slf4j generally never leaks to a module's exported package set
* Thus there's no actual harm in allowing this, and much benefit - 
especially if B and C (in your example) are not completely under your 
control (which is inevitable in any nontrivial system)


--
- DML


Re: Avoiding same-package conflicts

2015-10-29 Thread Karl Sanders
Hi Alex,

indeed I'm on JDK 8 but at the moment I don't have different versions
of the same library in the classpath.
However sooner or later I will have to satisfy this requirement.
I can wait the year or so that separates us from the GA release of JDK
9 but I'm afraid that Jigsaw won't be able to help me.
Hence my questions.

Also, just for the record, I understand that having multiple versions
of the same library isn't a best practice to say the least.
But I'm afraid that this is one of the cases where the library vendor
can't modify the current code to fit my requirements and extracting
the part that I need from an older version and refactoring it into a
separate library would be quite an undertaking.

Thanks for your time.

Cheers,
Karl

On Thu, Oct 29, 2015 at 1:03 AM, Alex Buckley  wrote:
> Hi Karl,
>
> Serious question: does your Java SE application expect that different
> versions of the same library are placed on the classpath in JDK 8?
>
> Alex
>
>
> On 10/28/2015 1:34 PM, Karl Sanders wrote:
>>
>> Hi,
>>
>> I'm trying out the JDK 9 EA with Jigsaw.
>>
>> I created two modules, A and B, which are required by module C.
>>
>> Modules A and B contain a non-exported package with the same name.
>>
>> After compiling each module separately I start module C and get a
>> java.lang.reflect.LayerInstantiationException saying that modules A
>> and B contain a package with the same name.
>>
>> In light of this behaviour I have two questions.
>>
>> - Is it correct to say that for a simple Java SE application to work
>> with this configuration the only solution, in the realm of what will
>> be provided with the GA version of JDK 9, is through the concept of
>> layers of modules?
>>
>> - In that case will there be some sort of out-of-the box functionality
>> to have this scenario work or will I have to write some non-trivial
>> code to manage these layers?
>>
>> In other words, I have to use different versions of the same library
>> in a Java SE application.
>> Since Jigsaw is approaching I thought I could wait for it instead of
>> learning and having to deal with OSGi.
>> But from what I see by using only Jigsaw I won't be able to satisfy
>> this requirement.
>> At least not without writing some non-trivial code that I'm afraid is
>> above my skill level.
>>
>> Cheers,
>> Karl
>>
>


Re: Avoiding same-package conflicts

2015-10-28 Thread Alex Buckley

Hi Karl,

Serious question: does your Java SE application expect that different 
versions of the same library are placed on the classpath in JDK 8?


Alex

On 10/28/2015 1:34 PM, Karl Sanders wrote:

Hi,

I'm trying out the JDK 9 EA with Jigsaw.

I created two modules, A and B, which are required by module C.

Modules A and B contain a non-exported package with the same name.

After compiling each module separately I start module C and get a
java.lang.reflect.LayerInstantiationException saying that modules A
and B contain a package with the same name.

In light of this behaviour I have two questions.

- Is it correct to say that for a simple Java SE application to work
with this configuration the only solution, in the realm of what will
be provided with the GA version of JDK 9, is through the concept of
layers of modules?

- In that case will there be some sort of out-of-the box functionality
to have this scenario work or will I have to write some non-trivial
code to manage these layers?

In other words, I have to use different versions of the same library
in a Java SE application.
Since Jigsaw is approaching I thought I could wait for it instead of
learning and having to deal with OSGi.
But from what I see by using only Jigsaw I won't be able to satisfy
this requirement.
At least not without writing some non-trivial code that I'm afraid is
above my skill level.

Cheers,
Karl