You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Trustin Lee <tr...@gmail.com> on 2007/01/18 09:04:34 UTC

Cyclic dependencies

Hi folks,

Today, I ran JDepend4Eclipse (http://andrei.gmxhome.de/jdepend4eclipse/) on
mina-core.  It seems like almost all packages have cyclic dependency.  It is
basically because we are using 'support' packages.  We moved all supportive
classes, that users don't need to know about, to 'support' package.  For
example, org.apache.mina.common depends on org.apache.mina.common.support,
and vice versa.  There's no functional problem with this issue, but we might
introduce a unwanted cyclic dependency because we can't keep track of *real*
cyclic dependencies because of false positives.

Is it time to reorganize the package structure?

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: Cyclic dependencies

Posted by "John E. Conlon" <jc...@verticon.com>.
Trustin Lee wrote:
> On 2/3/07, John E. Conlon <jc...@verticon.com> wrote:
>>
>> Trustin,
>>
>> Below are the OSGi related entries generated for the mina-core and added
>> to jar's manifest.mf .  Note the Export-Package and the Import-Package
>> entries.  These two metadata entries along with the Bundle-SymbolicName,
>> and the  Bundle-Version are used by the OSGi runtime to create a
>> classloader matrix that wires the Mina-Core bundle to its dependencies
>> and as a dependency for other bundles.
>>
>> The mina-core bundle manifest below specifies to the OSGi runtime to
>> export of all the packages in mina-core to the outside world, import the
>> slf4j package and also import all the exported packages as well.  The
>> latter may seem unwanted but in an OSGi runtime one may have multiple
>> mina-core bundles installed.  To quote -Richard Hall, Apache Felix.
>> " Yes, that is intended because it allows those packages to be
>> substitutable with other providers. If your bundle only exported them,
>> then it would always get them from itself, even in cases where there was
>> another provider already in use. This would then limit interoperability,
>> because your bundle would not be able to interact with bundles using the
>> other provider's packages. You can explicitly tell the plugin to not
>> import an exported package if you do not want this behavior. "
>>
>> Also notice the 'uses' attribute for the exported packages.  The 'uses'
>> metadata gives additional hints for wiring the classloader matrix
>> between bundles.  Perhaps you may find this metadata useful to you in
>> your refactoring the cyclic dependencies out of mina?
>>
>> The OSGi classloader matrix offers a continuation of the same idea of
>> Java encapsulation taken to a package level -> private, default, public,
>> and now Export-Package.  With OSGi we can encapsulate as much as
>> possible inside the module, exposing only as exportable the packages
>> with classes needed by our mina-core user bundles.
>
>
> I see.  You are a great OSGi teacher.  Thanks for quick-start 
> education.  :)
>
> I already identified cyclic dependencies using JDepends.
>
> So the first thing you can help me with is to identify all the packages
>> that we should specify as private to  the plugin. Meaning what packages
>> do we not want to offer to the outside world. These private packages
>> would contain internal classes that are only used within the mina-core.
>> In other words, internal classes are those that would never be inherited
>> or appear in a method signature by a class in a bundle other than the
>> mina-core.
>
>
> Because I am going to restructure the current package structure, I can't
> tell which packages will become private yet.  
Makes perfect sense.  The good news is,  that with module encapsulation 
you now have a new encapsulation construct to consider taking advantage 
of in the new design.
> The packages are mixed up now
> and private and public classes sometimes exist together.
And that is reflected by all the packages being exported now by the plugin.

>
> And I have a few questions.
>
> 1) Can't we control the access in a class-level instead of a 
> package-level?
> 2) Does class access modifier (e.g. class PackagePrivateClass) work
> correctly in OSGi?
Yes to #2. This is Java after all, so all the class access modifiers 
work as expected package(aka default), private, public and protected. 
The new aspect OSGi offers for us at this point is an intelligent 
container that wires our dependencies.  I call it the OSGi 'classloader 
matrix';-)

No to #1.  The wiring instructions (metadata) are oriented for matching 
bundle packages.

>
> If the answer of the second question is 'yes', then we could 
> restructure the
> packages and make package-private classes have appropriate access 
> modifier (
> i.e. (package)), rather than prohibiting access to the whole classes of a
> certain package.
Yes that can be done and we can just export everything.  But I think you 
will find it more useful to move what changes behind stable interfaces, 
factories, utilities that are in exported packages.  All implementations 
can be moved to private packages that are not exported.  Developers 
using Mina can then build their Mina infrastructures on stable 
interfaces/factories/utilities that are offered in the exported 
packages.  Packages with classes they care about are accessible things 
they don't - aren't.  Tightens up the docs, lessens the learning curve 
and moves us away from module(aka jar) development time coupling. We can 
rev our private packages release to release without impact, because now 
we are decoupled at the module/jar level and loosely coupled at the 
package level.  (Did I mention we can add version and version-range 
attributes to our imports and export metadata to insure only what we or 
our users is getting what we require?)  

Maven and Ivy provides the dependency matrix for developers at dev time 
between modules.  With OSGi we can now push this dependency coupling 
down to the package level and out to the deploy/run time.
 
> For now, users should have no access to *.support, but this will change
> after restructuring.
>
I will commit my plug-in changes to mina-core. As you move forward with 
the redesign we can tune the plugin to hide our private packages. (If 
you elect to use private packages. )  Later on if we want, we can 
gradually add more metadata to tighten up our export and imports to 
achieve a higher degree of deploy and runtime agility.

cheers,
John


Re: Cyclic dependencies

Posted by Trustin Lee <tr...@gmail.com>.
On 2/3/07, John E. Conlon <jc...@verticon.com> wrote:
>
> Trustin,
>
> Below are the OSGi related entries generated for the mina-core and added
> to jar's manifest.mf .  Note the Export-Package and the Import-Package
> entries.  These two metadata entries along with the Bundle-SymbolicName,
> and the  Bundle-Version are used by the OSGi runtime to create a
> classloader matrix that wires the Mina-Core bundle to its dependencies
> and as a dependency for other bundles.
>
> The mina-core bundle manifest below specifies to the OSGi runtime to
> export of all the packages in mina-core to the outside world, import the
> slf4j package and also import all the exported packages as well.  The
> latter may seem unwanted but in an OSGi runtime one may have multiple
> mina-core bundles installed.  To quote -Richard Hall, Apache Felix.
> " Yes, that is intended because it allows those packages to be
> substitutable with other providers. If your bundle only exported them,
> then it would always get them from itself, even in cases where there was
> another provider already in use. This would then limit interoperability,
> because your bundle would not be able to interact with bundles using the
> other provider's packages. You can explicitly tell the plugin to not
> import an exported package if you do not want this behavior. "
>
> Also notice the 'uses' attribute for the exported packages.  The 'uses'
> metadata gives additional hints for wiring the classloader matrix
> between bundles.  Perhaps you may find this metadata useful to you in
> your refactoring the cyclic dependencies out of mina?
>
> The OSGi classloader matrix offers a continuation of the same idea of
> Java encapsulation taken to a package level -> private, default, public,
> and now Export-Package.  With OSGi we can encapsulate as much as
> possible inside the module, exposing only as exportable the packages
> with classes needed by our mina-core user bundles.


I see.  You are a great OSGi teacher.  Thanks for quick-start education.  :)

I already identified cyclic dependencies using JDepends.

So the first thing you can help me with is to identify all the packages
> that we should specify as private to  the plugin. Meaning what packages
> do we not want to offer to the outside world. These private packages
> would contain internal classes that are only used within the mina-core.
> In other words, internal classes are those that would never be inherited
> or appear in a method signature by a class in a bundle other than the
> mina-core.


Because I am going to restructure the current package structure, I can't
tell which packages will become private yet.  The packages are mixed up now
and private and public classes sometimes exist together.

And I have a few questions.

1) Can't we control the access in a class-level instead of a package-level?
2) Does class access modifier (e.g. class PackagePrivateClass) work
correctly in OSGi?

If the answer of the second question is 'yes', then we could restructure the
packages and make package-private classes have appropriate access modifier (
i.e. (package)), rather than prohibiting access to the whole classes of a
certain package.

For now, users should have no access to *.support, but this will change
after restructuring.

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: Cyclic dependencies

Posted by "John E. Conlon" <jc...@verticon.com>.
Trustin,

Below are the OSGi related entries generated for the mina-core and added 
to jar's manifest.mf .  Note the Export-Package and the Import-Package 
entries.  These two metadata entries along with the Bundle-SymbolicName, 
and the  Bundle-Version are used by the OSGi runtime to create a 
classloader matrix that wires the Mina-Core bundle to its dependencies 
and as a dependency for other bundles. 

The mina-core bundle manifest below specifies to the OSGi runtime to 
export of all the packages in mina-core to the outside world, import the 
slf4j package and also import all the exported packages as well.  The 
latter may seem unwanted but in an OSGi runtime one may have multiple 
mina-core bundles installed.  To quote -Richard Hall, Apache Felix.
" Yes, that is intended because it allows those packages to be
substitutable with other providers. If your bundle only exported them,
then it would always get them from itself, even in cases where there was
another provider already in use. This would then limit interoperability,
because your bundle would not be able to interact with bundles using the
other provider's packages. You can explicitly tell the plugin to not
import an exported package if you do not want this behavior. "

Also notice the 'uses' attribute for the exported packages.  The 'uses' 
metadata gives additional hints for wiring the classloader matrix 
between bundles.  Perhaps you may find this metadata useful to you in 
your refactoring the cyclic dependencies out of mina?

The OSGi classloader matrix offers a continuation of the same idea of 
Java encapsulation taken to a package level -> private, default, public, 
and now Export-Package.  With OSGi we can encapsulate as much as 
possible inside the module, exposing only as exportable the packages 
with classes needed by our mina-core user bundles.  

So the first thing you can help me with is to identify all the packages 
that we should specify as private to  the plugin. Meaning what packages 
do we not want to offer to the outside world. These private packages 
would contain internal classes that are only used within the mina-core.  
In other words, internal classes are those that would never be inherited 
or appear in a method signature by a class in a bundle other than the 
mina-core. 


============================================================================================
Bundle-Description           MINA (Multipurpose Infrastructure for 
Network Applications) is a   network application framework which helps 
users develop high   performance and highly scalable network 
applications easily.
Bundle-DocURL                http://mina.apace.org/
Bundle-License               http://www.apache.org/licenses/LICENSE-2.0
Bundle-ManifestVersion       2
Bundle-Name                  Apache MINA Core API
Bundle-SymbolicName          mina-core
Bundle-Vendor                Apache MINA Project
Bundle-Version               2.0.0.M1-SNAPSHOT
Created-By                   Bnd-0.0.107
Export-Package               
org.apache.mina.transport.vmpipe;uses:="org.apache.mina.common.support,org.apache.mina.common,org.apache.mina.util,org.apache.mina.transport.vmpipe.support",
org.apache.mina.filter.executor;uses:="org.apache.mina.common,org.slf4j",
org.apache.mina.common;uses:="org.apache.mina.transport.vmpipe,org.apache.mina.common.support,org.apache.mina.util,org.apache.mina.transport.socket.nio",
org.apache.mina.transport.socket.nio.support;uses:="org.apache.mina.common.support,org.apache.mina.common,org.apache.mina.util,org.apache.mina.transport.socket.nio",
org.apache.mina.transport.socket.nio;uses:="org.apache.mina.common.support,org.apache.mina.common,org.apache.mina.util,org.apache.mina.transport.socket.nio.support",
org.apache.mina.handler.chain;uses:=org.apache.mina.common,
org.apache.mina.handler.multiton;uses:="org.apache.mina.common,org.apache.mina.util",
org.apache.mina.transport.vmpipe.support;uses:="org.apache.mina.transport.vmpipe,org.apache.mina.common.support,org.apache.mina.common,org.apache.mina.util",
org.apache.mina.handler.demux;uses:="org.apache.mina.common,org.apache.mina.util",
org.apache.mina.common.support;uses:="org.apache.mina.common,org.apache.mina.util,org.slf4j",
org.apache.mina.handler.support;uses:=org.apache.mina.common,
org.apache.mina.filter.codec.textline;uses:="org.apache.mina.common,org.apache.mina.util,org.apache.mina.filter.codec",
org.apache.mina.management;uses:=org.apache.mina.common,
org.apache.mina.filter.codec.support;uses:="org.apache.mina.common.support,org.apache.mina.common,org.apache.mina.filter.codec",
org.apache.mina.util;uses:="org.apache.mina.common,org.apache.mina.transport.socket.nio,org.slf4j",
org.apache.mina.filter;uses:="org.apache.mina.filter.executor,org.apache.mina.common,org.apache.mina.util,org.slf4j",
org.apache.mina.filter.codec.serialization;uses:="org.apache.mina.common,org.apache.mina.filter.codec",
org.apache.mina.filter.codec.demux;uses:="org.apache.mina.common,org.apache.mina.util,org.apache.mina.filter.codec",
org.apache.mina.filter.codec;uses:="org.apache.mina.common.support,org.apache.mina.common,org.apache.mina.filter.codec.support,org.apache.mina.util",
org.apache.mina.handler;uses:="org.apache.mina.handler.support,org.apache.mina.common,org.apache.mina.util"

Import-Package              
org.apache.mina.common,
org.apache.mina.common.support,
org.apache.mina.filter,
org.apache.mina.filter.codec,
org.apache.mina.filter.codec.demux,
org.apache.mina.filter.codec.serialization,
org.apache.mina.filter.codec.support,
org.apache.mina.filter.codec.textline,
org.apache.mina.filter.executor,
org.apache.mina.handler,
org.apache.mina.handler.chain,
org.apache.mina.handler.demux,
org.apache.mina.handler.multiton,
org.apache.mina.handler.support,
org.apache.mina.management,
org.apache.mina.transport.socket.nio,
org.apache.mina.transport.socket.nio.support,
org.apache.mina.transport.vmpipe,
org.apache.mina.transport.vmpipe.support,
org.apache.mina.util,
org.slf4j

Include-Resource             src/main/resources/
Manifest-Version             1
=======================================================================================
cheers,
John

Re: Cyclic dependencies

Posted by Trustin Lee <tr...@gmail.com>.
Hi John,

On 2/3/07, John E. Conlon <jc...@verticon.com> wrote:
>
> Trustin Lee wrote:
> > On 2/2/07, *John E. Conlon* <jconlon@verticon.com
> > <ma...@verticon.com>> wrote:
> >
> >     Hi Trustin,
> >
> >     Not sure if you were planing to refactor to consolidate the 'split
> >     packages'  for the 2.0.0-M1 trunk or not.
> >
> >
> > I'm not yet sure about 'how granularly' split the packages, but I'm
> > sure that I will make the changes you suggested.
> >
> >     If SO: let me know when and I will follow you and create the OSGi
> >     metadata in the jar manifests so we can have a Mina release with
> jars
> >     that can act as OSGi bundles.
> >
> >
> > I have no specific schedule yet because it's not my day job.  Any
> > committer who's interested in this task, including you, can make the
> > changes.  Of course, I'll ping you when I am finished.
> May I propose that we do this together?  By collaborating we can better
> tune the package export and import policies to the outer world from the
> module (aka jar, OSGi bundle) standpoint.  With the information we
> gather from this effort in mind we can better understand where we want
> to go with the package refactoring.


Sure.  Let me read your additional message and reply to it now.

Will start by adding OSGi metadata to the existing core package.  Will
> do this adding the maven-bundle-plugin from Apache Felix to the pom.xml.
> See: http://cwiki.apache.org/FELIX/bundle-plugin-for-maven-bnd.html
> The plugin will parse all classes in the classpath to determine external
> dependencies and with these create the OSGi metadata. This metadata will
> prove very helpful to us for understanding how we can clean up our
> structure with by refactoring.


I see.  Sounds great!

Cheers,
Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: Cyclic dependencies

Posted by "John E. Conlon" <jc...@verticon.com>.
Trustin Lee wrote:
> On 2/2/07, *John E. Conlon* <jconlon@verticon.com 
> <ma...@verticon.com>> wrote:
>
>     Hi Trustin,
>
>     Not sure if you were planing to refactor to consolidate the 'split
>     packages'  for the 2.0.0-M1 trunk or not.
>
>
> I'm not yet sure about 'how granularly' split the packages, but I'm 
> sure that I will make the changes you suggested.
>
>     If SO: let me know when and I will follow you and create the OSGi
>     metadata in the jar manifests so we can have a Mina release with jars
>     that can act as OSGi bundles.
>
>
> I have no specific schedule yet because it's not my day job.  Any 
> committer who's interested in this task, including you, can make the 
> changes.  Of course, I'll ping you when I am finished.
May I propose that we do this together?  By collaborating we can better 
tune the package export and import policies to the outer world from the 
module (aka jar, OSGi bundle) standpoint.  With the information we 
gather from this effort in mind we can better understand where we want 
to go with the package refactoring.

Will start by adding OSGi metadata to the existing core package.  Will 
do this adding the maven-bundle-plugin from Apache Felix to the pom.xml. 
See: http://cwiki.apache.org/FELIX/bundle-plugin-for-maven-bnd.html
The plugin will parse all classes in the classpath to determine external 
dependencies and with these create the OSGi metadata. This metadata will 
prove very helpful to us for understanding how we can clean up our 
structure with by refactoring.

cheers,
John

>
> Trustin
> -- 
> what we call human nature is actually human habit
> --
> http://gleamynode.net/
> --
> PGP key fingerprints:
> * E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
> * B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6 


Re: Cyclic dependencies

Posted by Trustin Lee <tr...@gmail.com>.
On 2/2/07, John E. Conlon <jc...@verticon.com> wrote:
>
> Hi Trustin,
>
> Not sure if you were planing to refactor to consolidate the 'split
> packages'  for the 2.0.0-M1 trunk or not.


I'm not yet sure about 'how granularly' split the packages, but I'm sure
that I will make the changes you suggested.

If SO: let me know when and I will follow you and create the OSGi
> metadata in the jar manifests so we can have a Mina release with jars
> that can act as OSGi bundles.


I have no specific schedule yet because it's not my day job.  Any committer
who's interested in this task, including you, can make the changes.  Of
course, I'll ping you when I am finished.

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: Cyclic dependencies

Posted by "John E. Conlon" <jc...@verticon.com>.
Hi Trustin,

Not sure if you were planing to refactor to consolidate the 'split
packages'  for the 2.0.0-M1 trunk or not.  

If SO: let me know when and I will follow you and create the OSGi
metadata in the jar manifests so we can have a Mina release with jars
that can act as OSGi bundles.

If NOT: let me know now so I can begin work on creating the OSGi
metadata in the jars for doing the same thing. (Still will work but Only
not as good as 'If SO')


cheers,
John


On Sun, 2007-01-21 at 08:11 +0900, Trustin Lee wrote:
> On 1/19/07, John E. Conlon <jc...@verticon.com> wrote:
> >
> > Can we also consider moving the classes in the two packages
> > org.apache.mina.filter and org.apache.mina.filter.support or renaming
> > these packages so that they are not fragmented across the filter-ssl and
> > the filter-compression projects?
> >
> > Doing this will allow us to use one or a combination of mina project
> > artifacts (jars) into an orchestrated classloader hierarchy that
> > maintains class space consistency. Today mina can only work in this type
> > of environment when all its artifacts are combined into a single uber-
> > jar.
> >
> > See:
> > filter-ssl/src/main/java/org/apache/mina/filter/support
> > filter-compression/src/main/java/org/apache/mina/filter/support
> >
> > filter-ssl/src/main/java/org/apache/mina/filter
> > filter-compression/src/main/java/org/apache/mina/filter
> 
> 
> Let me fix this issue in 2.0.0-M1.  We really need package reorganization.
> Sorry for not fixing it for a long time.
> 
> Thanks,
> Trustin


Re: Cyclic dependencies

Posted by Trustin Lee <tr...@gmail.com>.
On 1/19/07, John E. Conlon <jc...@verticon.com> wrote:
>
> Can we also consider moving the classes in the two packages
> org.apache.mina.filter and org.apache.mina.filter.support or renaming
> these packages so that they are not fragmented across the filter-ssl and
> the filter-compression projects?
>
> Doing this will allow us to use one or a combination of mina project
> artifacts (jars) into an orchestrated classloader hierarchy that
> maintains class space consistency. Today mina can only work in this type
> of environment when all its artifacts are combined into a single uber-
> jar.
>
> See:
> filter-ssl/src/main/java/org/apache/mina/filter/support
> filter-compression/src/main/java/org/apache/mina/filter/support
>
> filter-ssl/src/main/java/org/apache/mina/filter
> filter-compression/src/main/java/org/apache/mina/filter


Let me fix this issue in 2.0.0-M1.  We really need package reorganization.
Sorry for not fixing it for a long time.

Thanks,
Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: Cyclic dependencies

Posted by "John E. Conlon" <jc...@verticon.com>.
Can we also consider moving the classes in the two packages
org.apache.mina.filter and org.apache.mina.filter.support or renaming
these packages so that they are not fragmented across the filter-ssl and
the filter-compression projects? 

Doing this will allow us to use one or a combination of mina project
artifacts (jars) into an orchestrated classloader hierarchy that
maintains class space consistency. Today mina can only work in this type
of environment when all its artifacts are combined into a single uber-
jar. 

See:
filter-ssl/src/main/java/org/apache/mina/filter/support
filter-compression/src/main/java/org/apache/mina/filter/support

filter-ssl/src/main/java/org/apache/mina/filter
filter-compression/src/main/java/org/apache/mina/filter

cheers,
John

On Thu, 2007-01-18 at 17:04 +0900, Trustin Lee wrote:
> Hi folks,
> 
> Today, I ran JDepend4Eclipse (http://andrei.gmxhome.de/jdepend4eclipse/) on
> mina-core.  It seems like almost all packages have cyclic dependency.  It is
> basically because we are using 'support' packages.  We moved all supportive
> classes, that users don't need to know about, to 'support' package.  For
> example, org.apache.mina.common depends on org.apache.mina.common.support,
> and vice versa.  There's no functional problem with this issue, but we might
> introduce a unwanted cyclic dependency because we can't keep track of *real*
> cyclic dependencies because of false positives.
> 
> Is it time to reorganize the package structure?
> 
> Trustin