River
  1. River
  2. RIVER-300

introduce maven to the river build process

    Details

    • Type: Improvement Improvement
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: build
    • Labels:
      None

      Description

      Currently the river build using ant, but it's a custom build process and has many hang overs from the original make build.
      Given that the project has no 3rd party dependencies, it would be very easy to break the code up into modules.

      Please feel free to add to this JIRA if you have any opinions on how the maven repository should be setup.

      1. apache-river-gradle.zip
        3.34 MB
        Dennis Reedy
      2. apache-river-maven.zip
        1.90 MB
        Dennis Reedy
      3. river-modularization-overview.odt
        41 kB
        Dennis Reedy
      4. river-modularization-overview.pdf
        88 kB
        Dennis Reedy
      5. persistOutrigger.pdf
        226 kB
        Peter Firmstone
      6. ldm.pdf
        77 kB
        Peter Firmstone
      7. lld.pdf
        58 kB
        Peter Firmstone

        Issue Links

          Activity

          Hide
          Greg Trasuk added a comment -

          I propose that we close this issue as "won't fix". We currently have in place the capability to publish the produced jars to Maven Central. Restructuring or modularizing the build may be appropriate if/when River components are modified, but I would suggest it's not an end in itself.

          Greg.

          Show
          Greg Trasuk added a comment - I propose that we close this issue as "won't fix". We currently have in place the capability to publish the produced jars to Maven Central. Restructuring or modularizing the build may be appropriate if/when River components are modified, but I would suggest it's not an end in itself. Greg.
          Hide
          Peter Firmstone added a comment -

          Many classes in the existing build, belonging to the com.sun.jini.* namespace are duplicated in jar archives, these are implementation classes, the preferred class loading mechanism is used to ensure that the codebase copy / version is used by proxy's, not the classpath version of a class.

          Preferred class loading prevents the loading of jini implementation classes from the Classpath (application class loader) by proxy's or services in their own namespace (a child classloader).

          If we create a modular system, these implementation classes duplicated in many archives currently, will need to be separated into their own module, in order to allow them and the modules that depend on them, to evolve separately, since a proxy will need to be able to use the version it requires, while the platform can use another version.

          Preferred class loading, is the current mechanism that should be used to assist with version control, to ensure that proxy's load the correct implementation classes. This allows TaskManager and suchlike to evolve without concern for backward compatibility, and it allows services and proxy's to use their own version copies, in their own private name space.

          Preferred class loading is required to prevent the use of classes from the classpath (application class loader)

          In a modular system, the source code belongs in a particular module and is not duplicated, classes are also not duplicated. The class files that are currently duplicated belong in their own modules, on which the platform and other modules depend.

          This is at present, the only way to prevent us from having to support the duplicated implementation classes as part of the platform.

          Eventually I can see the potential to refactor using JDepend and dependency inversion, removing jini platform implementation classes from the classpath, instead loading them into a private namespace (child classloader), when this is done, preferred class loading will no longer be mandatory, as there is no danger of proxy's using the local class path version of these classes, since they won't be visible in the parent application classloader.

          Show
          Peter Firmstone added a comment - Many classes in the existing build, belonging to the com.sun.jini.* namespace are duplicated in jar archives, these are implementation classes, the preferred class loading mechanism is used to ensure that the codebase copy / version is used by proxy's, not the classpath version of a class. Preferred class loading prevents the loading of jini implementation classes from the Classpath (application class loader) by proxy's or services in their own namespace (a child classloader). If we create a modular system, these implementation classes duplicated in many archives currently, will need to be separated into their own module, in order to allow them and the modules that depend on them, to evolve separately, since a proxy will need to be able to use the version it requires, while the platform can use another version. Preferred class loading, is the current mechanism that should be used to assist with version control, to ensure that proxy's load the correct implementation classes. This allows TaskManager and suchlike to evolve without concern for backward compatibility, and it allows services and proxy's to use their own version copies, in their own private name space. Preferred class loading is required to prevent the use of classes from the classpath (application class loader) In a modular system, the source code belongs in a particular module and is not duplicated, classes are also not duplicated. The class files that are currently duplicated belong in their own modules, on which the platform and other modules depend. This is at present, the only way to prevent us from having to support the duplicated implementation classes as part of the platform. Eventually I can see the potential to refactor using JDepend and dependency inversion, removing jini platform implementation classes from the classpath, instead loading them into a private namespace (child classloader), when this is done, preferred class loading will no longer be mandatory, as there is no danger of proxy's using the local class path version of these classes, since they won't be visible in the parent application classloader.
          Hide
          Peter Firmstone added a comment -

          I can see where Dennis is coming from, Renaming river-dl.jar to river-api.jar, since this jar is depended upon by river-lib.jar, so in a modular build, the class files in river-dl.jar and river-lib.jar are not duplicated, requiring both these jar files to be loaded by applications utilising river-lib.jar.

          The minimum requirements for a Jini environment is the platform.jar, so the river-dl.jar still needs to be downloaded where the client node lacks the classes a proxy needs that are provided by river-dl.jar. In this case those class files will be loaded into the proxy's classloader.

          Client in this case refers to a node that doesn't contain river-lib.jar or river-dl.jar on the classpath. This doesn't mean this client doesn't also provide services to other nodes, although this configuration would be rare.

          River-lib.jar contains a lot of useful jar files also, such as additional service api and service management utilities.

          What I have noted is the platform.jar contains a minimal number of implementation classes, while river-lib.jar contains a lot.

          So perhaps we should do as Dennis has suggested and just make the modular build an exercise in mostly replicating the current build, albeit without class duplication. Although as Gregg has pointed out, we must be careful to consider compatibility.

          I was reading the JDepend website, I think Chris can see where I'd like to go, thanks for the info & links:

          "Invert Dependencies
          The goal of using JDepend is to ultimately invert package dependencies such that low-abstraction packages depend upon high-abstraction packages. This inversion of dependencies allows the high-abstraction packages to be reused independently while being extensible to an open set of implementations. In general, dependencies upon stable packages are desirable, while dependencies upon instable packages are undesirable. JDepend allows dependencies to be iteratively examined and refactored as an integral part of software design and development. "

          Seems like a good long term goal.

          When the package dependencies have been inverted, the implementations can go into child class loaders, while the high abstraction packages become the common classes that proxy's, applications and services use to communicate with each other belong in the parent application class loader.

          Implementation classes belong in child classloaders with application, proxy and service implementations. Allowing more flexibility and evolution of implementations.

          This does make me realise though we'll need to load river-lib.jar into the applicaiton class loader for some time.

          Show
          Peter Firmstone added a comment - I can see where Dennis is coming from, Renaming river-dl.jar to river-api.jar, since this jar is depended upon by river-lib.jar, so in a modular build, the class files in river-dl.jar and river-lib.jar are not duplicated, requiring both these jar files to be loaded by applications utilising river-lib.jar. The minimum requirements for a Jini environment is the platform.jar, so the river-dl.jar still needs to be downloaded where the client node lacks the classes a proxy needs that are provided by river-dl.jar. In this case those class files will be loaded into the proxy's classloader. Client in this case refers to a node that doesn't contain river-lib.jar or river-dl.jar on the classpath. This doesn't mean this client doesn't also provide services to other nodes, although this configuration would be rare. River-lib.jar contains a lot of useful jar files also, such as additional service api and service management utilities. What I have noted is the platform.jar contains a minimal number of implementation classes, while river-lib.jar contains a lot. So perhaps we should do as Dennis has suggested and just make the modular build an exercise in mostly replicating the current build, albeit without class duplication. Although as Gregg has pointed out, we must be careful to consider compatibility. I was reading the JDepend website, I think Chris can see where I'd like to go, thanks for the info & links: "Invert Dependencies The goal of using JDepend is to ultimately invert package dependencies such that low-abstraction packages depend upon high-abstraction packages. This inversion of dependencies allows the high-abstraction packages to be reused independently while being extensible to an open set of implementations. In general, dependencies upon stable packages are desirable, while dependencies upon instable packages are undesirable. JDepend allows dependencies to be iteratively examined and refactored as an integral part of software design and development. " Seems like a good long term goal. When the package dependencies have been inverted, the implementations can go into child class loaders, while the high abstraction packages become the common classes that proxy's, applications and services use to communicate with each other belong in the parent application class loader. Implementation classes belong in child classloaders with application, proxy and service implementations. Allowing more flexibility and evolution of implementations. This does make me realise though we'll need to load river-lib.jar into the applicaiton class loader for some time.
          Hide
          Gregg Wonderly added a comment -

          Peter, there is one very important constraint that we have to deal with. It has to be possible to unmarshal any services proxy that you can lookup, regardless of what classes are in your VM. The proxy's codebase must contain a version of everything needed to use the proxy. This means that you can't really take a "service' vs 'client' view of class segregation. The classes, interfaces must be "everywhere". The key separation of the service vs -dl jar file is simply the fact that you don't want "implementation" in the classpath, only in the codebase. Any other commoning of classes, for me, is a deal breaker because it greatly changes the opportunity that more than one service will be dependent on a "jar" that you change on a web server, and keep services from being independent of each other.

          Show
          Gregg Wonderly added a comment - Peter, there is one very important constraint that we have to deal with. It has to be possible to unmarshal any services proxy that you can lookup, regardless of what classes are in your VM. The proxy's codebase must contain a version of everything needed to use the proxy. This means that you can't really take a "service' vs 'client' view of class segregation. The classes, interfaces must be "everywhere". The key separation of the service vs -dl jar file is simply the fact that you don't want "implementation" in the classpath, only in the codebase. Any other commoning of classes, for me, is a deal breaker because it greatly changes the opportunity that more than one service will be dependent on a "jar" that you change on a web server, and keep services from being independent of each other.
          Peter Firmstone made changes -
          Attachment persistOutrigger.pdf [ 12469060 ]
          Attachment ldm.pdf [ 12469061 ]
          Attachment lld.pdf [ 12469062 ]
          Hide
          Peter Firmstone added a comment -

          Three pdf files of graphical dependency relationships between classes.

          These graphs each represent the dependencies of one of the following classes:

          com.sun.jini.outrigger.PersistentOutriggerImpl
          net.jini.discovery.LookupDiscoveryManager
          net.jini.discovery.LookupLocatorDiscovery

          Show
          Peter Firmstone added a comment - Three pdf files of graphical dependency relationships between classes. These graphs each represent the dependencies of one of the following classes: com.sun.jini.outrigger.PersistentOutriggerImpl net.jini.discovery.LookupDiscoveryManager net.jini.discovery.LookupLocatorDiscovery
          Hide
          Dennis Reedy added a comment -

          I dont see any reason to keep service-ui.jar in the mix as an additional artifact. The service UI work seems to fit in very nicely with the intent and purpose of jsk-dl (river-dl), breaking it out into it's own module seems overkill IMO.

          I would like to move ahead and change:

          river-dl -> river-api

          I think keeping river-lib as-is for now makes the most amount of sense. With this approach,

          river-lib – depends-on --> river-api

          Clients that want to use the service interfaces in river-api need only to include river-api in their classpath as a direct dependency. Consider if they want to simply discover a JavaSpace today, clients need to include (at least) jsk-dl.jar in their classpath (most likely clients include jsk-lib in their classpath).

          Show
          Dennis Reedy added a comment - I dont see any reason to keep service-ui.jar in the mix as an additional artifact. The service UI work seems to fit in very nicely with the intent and purpose of jsk-dl (river-dl), breaking it out into it's own module seems overkill IMO. I would like to move ahead and change: river-dl -> river-api I think keeping river-lib as-is for now makes the most amount of sense. With this approach, river-lib – depends-on --> river-api Clients that want to use the service interfaces in river-api need only to include river-api in their classpath as a direct dependency. Consider if they want to simply discover a JavaSpace today, clients need to include (at least) jsk-dl.jar in their classpath (most likely clients include jsk-lib in their classpath).
          Hide
          Peter Firmstone added a comment -

          Perhaps service-ui.jar should remain.

          These are the service interfaces not included in platform:

          net/jini/admin/Administrable.class
          net/jini/admin/JoinAdmin.class
          net/jini/discovery/LookupDiscoveryRegistration.class
          net/jini/discovery/LookupDiscoveryService.class
          net/jini/discovery/LookupUnmarshalException.class
          net/jini/entry/UnusableEntriesException.class
          net/jini/event/EventMailbox.class
          net/jini/event/MailboxRegistration.class
          net/jini/lease/LeaseRenewalService.class
          net/jini/lease/LeaseRenewalSet.class
          net/jini/lease/LeaseUnmarshalException.class
          net/jini/space/JavaSpace.class
          net/jini/space/JavaSpace05.class
          net/jini/space/MatchSet.class

          We could either include all these classes are included in the platform jar, or provide a river-service-api.jar.

          Interestingly, multicast discovery is not included in the platform either, only unicast discovery.

          The question is what do we want to include in the platform and commit to maintaining compatibility between releases? The platform should allow compatibility in a distributed environment between nodes with different versions. Only the platform and service api (including downstream developer service api) should be in the application classloader, everything else should be in a private namespace (child classloader), where each private namespace represents a proxy (remote), service or client that needs its implementation kept separate, but cooperates using the classes from the platform or service api (or service-ui).

          If everything else is dynamically download-able or provision-able, then it's also evolvable, eg TaskManager, can be changed, because nothing in the platform at present depends on it.

          The following classes are the complete dependency's of all service interfaces:

          com/sun/jini/collection/WeakIdentityMap.class
          com/sun/jini/collection/WeakIdentityMap$Key.class
          com/sun/jini/jeri/internal/runtime/Util.class
          com/sun/jini/jeri/internal/runtime/Util$ClientHostImpl.class
          com/sun/jini/jeri/internal/runtime/Util$ClientSubjectImpl.class
          com/sun/jini/jeri/internal/runtime/Util$IntegrityEnforcementImpl.class
          com/sun/jini/jeri/internal/runtime/Util$LazyMethodToHash_Map.class
          com/sun/jini/jeri/internal/runtime/Util$TableCache.class
          com/sun/jini/logging/Levels.class
          com/sun/jini/logging/Levels$ClassReplacingObjectOutputStream.class
          com/sun/jini/logging/Levels$LevelData.class
          com/sun/jini/resource/Service.class
          com/sun/jini/resource/Service$1.class
          com/sun/jini/resource/Service$LazyIterator.class
          com/sun/jini/resource/ServiceConfigurationError.class
          net/jini/admin/Administrable.class
          net/jini/admin/JoinAdmin.class
          net/jini/core/discovery/LookupLocator.class
          net/jini/core/discovery/LookupLocator$1.class
          net/jini/core/entry/Entry.class
          net/jini/core/entry/UnusableEntryException.class
          net/jini/core/event/EventRegistration.class
          net/jini/core/event/RemoteEvent.class
          net/jini/core/event/RemoteEventListener.class
          net/jini/core/event/UnknownEventException.class
          net/jini/core/lease/Lease.class
          net/jini/core/lease/LeaseDeniedException.class
          net/jini/core/lease/LeaseException.class
          net/jini/core/lease/LeaseMap.class
          net/jini/core/lease/LeaseMapException.class
          net/jini/core/lease/UnknownLeaseException.class
          net/jini/core/lookup/ServiceID.class
          net/jini/core/lookup/ServiceItem.class
          net/jini/core/lookup/ServiceMatches.class
          net/jini/core/lookup/ServiceRegistrar.class
          net/jini/core/lookup/ServiceRegistration.class
          net/jini/core/lookup/ServiceTemplate.class
          net/jini/core/transaction/CannotAbortException.class
          net/jini/core/transaction/CannotCommitException.class
          net/jini/core/transaction/CannotJoinException.class
          net/jini/core/transaction/NestableTransaction.class
          net/jini/core/transaction/NestableTransaction$Created.class
          net/jini/core/transaction/TimeoutExpiredException.class
          net/jini/core/transaction/Transaction.class
          net/jini/core/transaction/Transaction$Created.class
          net/jini/core/transaction/TransactionException.class
          net/jini/core/transaction/UnknownTransactionException.class
          net/jini/core/transaction/server/CrashCountException.class
          net/jini/core/transaction/server/NestableTransactionManager.class
          net/jini/core/transaction/server/TransactionConstants.class
          net/jini/core/transaction/server/TransactionManager.class
          net/jini/core/transaction/server/TransactionManager$Created.class
          net/jini/core/transaction/server/TransactionParticipant.class
          net/jini/discovery/LookupDiscoveryRegistration.class
          net/jini/discovery/LookupDiscoveryService.class
          net/jini/discovery/LookupUnmarshalException.class
          net/jini/entry/UnusableEntriesException.class
          net/jini/event/EventMailbox.class
          net/jini/event/MailboxRegistration.class
          net/jini/export/ServerContext.class
          net/jini/export/ServerContext$1.class
          net/jini/export/ServerContext$Spi.class
          net/jini/io/context/ClientHost.class
          net/jini/io/context/ClientSubject.class
          net/jini/io/context/ContextPermission.class
          net/jini/io/context/IntegrityEnforcement.class
          net/jini/lease/LeaseRenewalService.class
          net/jini/lease/LeaseRenewalSet.class
          net/jini/lease/LeaseUnmarshalException.class
          net/jini/security/AccessPermission.class
          net/jini/security/GrantPermission.class
          net/jini/security/GrantPermission$1.class
          net/jini/security/GrantPermission$GrantPermissionCollection.class
          net/jini/security/GrantPermission$Implier.class
          net/jini/security/GrantPermission$PermissionInfo.class
          net/jini/security/IntegrityVerifier.class
          net/jini/security/Security.class
          net/jini/security/Security$1.class
          net/jini/security/Security$2.class
          net/jini/security/Security$3.class
          net/jini/security/Security$4.class
          net/jini/security/Security$5.class
          net/jini/security/Security$6.class
          net/jini/security/Security$7.class
          net/jini/security/Security$8.class
          net/jini/security/Security$ClassContextAccess.class
          net/jini/security/Security$Context.class
          net/jini/security/Security$Context$1.class
          net/jini/security/SecurityContext.class
          net/jini/security/TrustVerifier.class
          net/jini/security/TrustVerifier$Context.class
          net/jini/security/policy/DynamicPolicy.class
          net/jini/security/policy/SecurityContextSource.class
          net/jini/security/proxytrust/TrustEquivalence.class
          net/jini/space/JavaSpace.class
          net/jini/space/JavaSpace05.class
          net/jini/space/MatchSet.class

          Show
          Peter Firmstone added a comment - Perhaps service-ui.jar should remain. These are the service interfaces not included in platform: net/jini/admin/Administrable.class net/jini/admin/JoinAdmin.class net/jini/discovery/LookupDiscoveryRegistration.class net/jini/discovery/LookupDiscoveryService.class net/jini/discovery/LookupUnmarshalException.class net/jini/entry/UnusableEntriesException.class net/jini/event/EventMailbox.class net/jini/event/MailboxRegistration.class net/jini/lease/LeaseRenewalService.class net/jini/lease/LeaseRenewalSet.class net/jini/lease/LeaseUnmarshalException.class net/jini/space/JavaSpace.class net/jini/space/JavaSpace05.class net/jini/space/MatchSet.class We could either include all these classes are included in the platform jar, or provide a river-service-api.jar. Interestingly, multicast discovery is not included in the platform either, only unicast discovery. The question is what do we want to include in the platform and commit to maintaining compatibility between releases? The platform should allow compatibility in a distributed environment between nodes with different versions. Only the platform and service api (including downstream developer service api) should be in the application classloader, everything else should be in a private namespace (child classloader), where each private namespace represents a proxy (remote), service or client that needs its implementation kept separate, but cooperates using the classes from the platform or service api (or service-ui). If everything else is dynamically download-able or provision-able, then it's also evolvable, eg TaskManager, can be changed, because nothing in the platform at present depends on it. The following classes are the complete dependency's of all service interfaces: com/sun/jini/collection/WeakIdentityMap.class com/sun/jini/collection/WeakIdentityMap$Key.class com/sun/jini/jeri/internal/runtime/Util.class com/sun/jini/jeri/internal/runtime/Util$ClientHostImpl.class com/sun/jini/jeri/internal/runtime/Util$ClientSubjectImpl.class com/sun/jini/jeri/internal/runtime/Util$IntegrityEnforcementImpl.class com/sun/jini/jeri/internal/runtime/Util$LazyMethodToHash_Map.class com/sun/jini/jeri/internal/runtime/Util$TableCache.class com/sun/jini/logging/Levels.class com/sun/jini/logging/Levels$ClassReplacingObjectOutputStream.class com/sun/jini/logging/Levels$LevelData.class com/sun/jini/resource/Service.class com/sun/jini/resource/Service$1.class com/sun/jini/resource/Service$LazyIterator.class com/sun/jini/resource/ServiceConfigurationError.class net/jini/admin/Administrable.class net/jini/admin/JoinAdmin.class net/jini/core/discovery/LookupLocator.class net/jini/core/discovery/LookupLocator$1.class net/jini/core/entry/Entry.class net/jini/core/entry/UnusableEntryException.class net/jini/core/event/EventRegistration.class net/jini/core/event/RemoteEvent.class net/jini/core/event/RemoteEventListener.class net/jini/core/event/UnknownEventException.class net/jini/core/lease/Lease.class net/jini/core/lease/LeaseDeniedException.class net/jini/core/lease/LeaseException.class net/jini/core/lease/LeaseMap.class net/jini/core/lease/LeaseMapException.class net/jini/core/lease/UnknownLeaseException.class net/jini/core/lookup/ServiceID.class net/jini/core/lookup/ServiceItem.class net/jini/core/lookup/ServiceMatches.class net/jini/core/lookup/ServiceRegistrar.class net/jini/core/lookup/ServiceRegistration.class net/jini/core/lookup/ServiceTemplate.class net/jini/core/transaction/CannotAbortException.class net/jini/core/transaction/CannotCommitException.class net/jini/core/transaction/CannotJoinException.class net/jini/core/transaction/NestableTransaction.class net/jini/core/transaction/NestableTransaction$Created.class net/jini/core/transaction/TimeoutExpiredException.class net/jini/core/transaction/Transaction.class net/jini/core/transaction/Transaction$Created.class net/jini/core/transaction/TransactionException.class net/jini/core/transaction/UnknownTransactionException.class net/jini/core/transaction/server/CrashCountException.class net/jini/core/transaction/server/NestableTransactionManager.class net/jini/core/transaction/server/TransactionConstants.class net/jini/core/transaction/server/TransactionManager.class net/jini/core/transaction/server/TransactionManager$Created.class net/jini/core/transaction/server/TransactionParticipant.class net/jini/discovery/LookupDiscoveryRegistration.class net/jini/discovery/LookupDiscoveryService.class net/jini/discovery/LookupUnmarshalException.class net/jini/entry/UnusableEntriesException.class net/jini/event/EventMailbox.class net/jini/event/MailboxRegistration.class net/jini/export/ServerContext.class net/jini/export/ServerContext$1.class net/jini/export/ServerContext$Spi.class net/jini/io/context/ClientHost.class net/jini/io/context/ClientSubject.class net/jini/io/context/ContextPermission.class net/jini/io/context/IntegrityEnforcement.class net/jini/lease/LeaseRenewalService.class net/jini/lease/LeaseRenewalSet.class net/jini/lease/LeaseUnmarshalException.class net/jini/security/AccessPermission.class net/jini/security/GrantPermission.class net/jini/security/GrantPermission$1.class net/jini/security/GrantPermission$GrantPermissionCollection.class net/jini/security/GrantPermission$Implier.class net/jini/security/GrantPermission$PermissionInfo.class net/jini/security/IntegrityVerifier.class net/jini/security/Security.class net/jini/security/Security$1.class net/jini/security/Security$2.class net/jini/security/Security$3.class net/jini/security/Security$4.class net/jini/security/Security$5.class net/jini/security/Security$6.class net/jini/security/Security$7.class net/jini/security/Security$8.class net/jini/security/Security$ClassContextAccess.class net/jini/security/Security$Context.class net/jini/security/Security$Context$1.class net/jini/security/SecurityContext.class net/jini/security/TrustVerifier.class net/jini/security/TrustVerifier$Context.class net/jini/security/policy/DynamicPolicy.class net/jini/security/policy/SecurityContextSource.class net/jini/security/proxytrust/TrustEquivalence.class net/jini/space/JavaSpace.class net/jini/space/JavaSpace05.class net/jini/space/MatchSet.class
          Hide
          Dennis Reedy added a comment -

          Peter,

          (Side note: this format is getting hard to reference previous comments).

          > When you say the public API of services; interfaces and classes common to clients, services and proxy's These would be > the platform services in this case.

          I think this is the current jsk-lib.jar (and inclusively jsk-dl.jar).

          I think I see where you are going (still not sure), but perhaps this may help:

          The jsk-dl.jar (in this work effort river-dl) could really be re-named river-api (or river-client). These are the classes a client requires to use services.

          I dont think we need both river-dl and river-api (or river-client), they serve both the same purposes.

          The river-lib (depends on river-dl(or river-api/river-client pick one), gets those classes naturally through its dependency resolution and classpath.

          The change here is that river-api must be in the classpath of river-lib, it is no longer optional (as jsk-dl.jar was optioal in the classpath of jsk-lib.jar)

          Show
          Dennis Reedy added a comment - Peter, (Side note: this format is getting hard to reference previous comments). > When you say the public API of services; interfaces and classes common to clients, services and proxy's These would be > the platform services in this case. I think this is the current jsk-lib.jar (and inclusively jsk-dl.jar). I think I see where you are going (still not sure), but perhaps this may help: The jsk-dl.jar (in this work effort river-dl) could really be re-named river-api (or river-client). These are the classes a client requires to use services. I dont think we need both river-dl and river-api (or river-client), they serve both the same purposes. The river-lib (depends on river-dl(or river-api/river-client pick one), gets those classes naturally through its dependency resolution and classpath. The change here is that river-api must be in the classpath of river-lib, it is no longer optional (as jsk-dl.jar was optioal in the classpath of jsk-lib.jar)
          Hide
          Peter Firmstone added a comment -

          I've added a link to River-341, although I think we need to update that document.

          When I say Service API, I mean the public API of services; interfaces and classes common to clients, services and proxy's These would be the platform services in this case.

          These are the classes that you don't want to change, the end of protocols for Jini meant that protocols were replaced by java interfaces, these are those interfaces, the public api of services. An appropriate name might be jini-platform-service-api.jar

          The Service UI API contains classes and entry's that would also be common to clients, proxy's and services, although it can remain separate if necessary. (Are there still eager loading JVM's out there? I'm thinking of headless nodes).

          For example, the lease service's api is currently packaged in jsk-dl.jar (river-dl.jar), we don't really want it there, we want it to already be at the client.

          So to confirm the difference between the -api.jar and -dl.jar, the -dl.jar will depend on the -api.jar, which should be installed by the client.

          I think it would be likely that the river-platform.jar might depend on the jini-platform-service-api.jar also, in which case clients only depend on the river-platform.jar

          Show
          Peter Firmstone added a comment - I've added a link to River-341, although I think we need to update that document. When I say Service API, I mean the public API of services; interfaces and classes common to clients, services and proxy's These would be the platform services in this case. These are the classes that you don't want to change, the end of protocols for Jini meant that protocols were replaced by java interfaces, these are those interfaces, the public api of services. An appropriate name might be jini-platform-service-api.jar The Service UI API contains classes and entry's that would also be common to clients, proxy's and services, although it can remain separate if necessary. (Are there still eager loading JVM's out there? I'm thinking of headless nodes). For example, the lease service's api is currently packaged in jsk-dl.jar (river-dl.jar), we don't really want it there, we want it to already be at the client. So to confirm the difference between the -api.jar and -dl.jar, the -dl.jar will depend on the -api.jar, which should be installed by the client. I think it would be likely that the river-platform.jar might depend on the jini-platform-service-api.jar also, in which case clients only depend on the river-platform.jar
          Peter Firmstone made changes -
          Link This issue is related to RIVER-341 [ RIVER-341 ]
          Hide
          Gregg Wonderly added a comment -

          Peter can you detail what the difference between -api.jar and -dl.jar would be? Would -api.jar not contain any dependencies, and instead just be the base interfaces and classes used in the API? What would be the usage of this jar vs the -dl.jar?

          Show
          Gregg Wonderly added a comment - Peter can you detail what the difference between -api.jar and -dl.jar would be? Would -api.jar not contain any dependencies, and instead just be the base interfaces and classes used in the API? What would be the usage of this jar vs the -dl.jar?
          Hide
          Dennis Reedy added a comment -

          I dont understand what the Service API is. Right now the service UI work is already in river-dl

          Show
          Dennis Reedy added a comment - I dont understand what the Service API is. Right now the service UI work is already in river-dl
          Hide
          Peter Firmstone added a comment -

          Any objections to creating a jar that contains service UI and API?

          service-api.jar

          Show
          Peter Firmstone added a comment - Any objections to creating a jar that contains service UI and API? service-api.jar
          Hide
          Peter Firmstone added a comment -

          Modularisation of the directory structure and build of river is a large task, which might be used to replicate the current release artifacts, with the following exceptions:

          Due to the dependency nature and structure of a modular build (see Dennis Reedy's attached river-modularisation-overview), certain classes provided by primary modules are excluded from dependent modules, contrary to the existing build, where all dependent classes other than platform api classes are included.

          It is also worth noting modular dependency's and build structures are very relevant to Service API, to the implementation of services and proxy's and simplified development, which is possibly the main attraction of modular development frameworks.

          With existing Jini and River releases, each client can potentially have a different plethora of classes loaded by it's application class loader, preferred class loading has been provided to deal with this, which brings another set of issues, documented by Mike Warres.

          Sometimes change is an opportunity to consider other changes, such as the namespace change from com.sun.jini to org.apache.river, this is currently in the experimental stages and we're not certain if this should be done at the same time, but I'd like to keep the option open for now.

          Client developers have been made aware of a policy that com.sun.jini are implementation classes only and not to be used, however a number of useful utility classes are included in com.sun.jini and will likely cause some client breakage (not proxys which have preferred class loading), when they're moved.

          Making the build modular also makes our service implementations (that client developers are also free to implement) depend on parts of the build that are implementation only.

          Considering that the only thing guaranteed to be installed at all clients is the platform jar, it is typical for service proxy's to have all needed classes available to them via download, utilising preferred class loading to ensure these classes are loaded, and not substituted by classes already loaded in the application class loader. So even with a modular build, there is still a need to maintain a level of compatibility with existing installations. In reality we will need to provide a jar file containing all the classes needed by proxy's downloaded to legacy clients.

          In an ideal world, the application class loader would only contain classes and interfaces that are used by proxy's, client's and services to communicate with each other, child class loaders representing private namespaces would contain all implementation classes. In this world, preferred class loading would not be required and annotation loss would not occur. If the application classloader only contained service api and the jini platform, then a number of existing issues would disappear.

          So the question remains: Why was the current platform jar structured how it is now?

          What are the reasons and logic behind it's current design?

          I think these are questions we need to ask as we explore the possibilities of a modular build structure.

          Show
          Peter Firmstone added a comment - Modularisation of the directory structure and build of river is a large task, which might be used to replicate the current release artifacts, with the following exceptions: Due to the dependency nature and structure of a modular build (see Dennis Reedy's attached river-modularisation-overview), certain classes provided by primary modules are excluded from dependent modules, contrary to the existing build, where all dependent classes other than platform api classes are included. It is also worth noting modular dependency's and build structures are very relevant to Service API, to the implementation of services and proxy's and simplified development, which is possibly the main attraction of modular development frameworks. With existing Jini and River releases, each client can potentially have a different plethora of classes loaded by it's application class loader, preferred class loading has been provided to deal with this, which brings another set of issues, documented by Mike Warres. Sometimes change is an opportunity to consider other changes, such as the namespace change from com.sun.jini to org.apache.river, this is currently in the experimental stages and we're not certain if this should be done at the same time, but I'd like to keep the option open for now. Client developers have been made aware of a policy that com.sun.jini are implementation classes only and not to be used, however a number of useful utility classes are included in com.sun.jini and will likely cause some client breakage (not proxys which have preferred class loading), when they're moved. Making the build modular also makes our service implementations (that client developers are also free to implement) depend on parts of the build that are implementation only. Considering that the only thing guaranteed to be installed at all clients is the platform jar, it is typical for service proxy's to have all needed classes available to them via download, utilising preferred class loading to ensure these classes are loaded, and not substituted by classes already loaded in the application class loader. So even with a modular build, there is still a need to maintain a level of compatibility with existing installations. In reality we will need to provide a jar file containing all the classes needed by proxy's downloaded to legacy clients. In an ideal world, the application class loader would only contain classes and interfaces that are used by proxy's, client's and services to communicate with each other, child class loaders representing private namespaces would contain all implementation classes. In this world, preferred class loading would not be required and annotation loss would not occur. If the application classloader only contained service api and the jini platform, then a number of existing issues would disappear. So the question remains: Why was the current platform jar structured how it is now? What are the reasons and logic behind it's current design? I think these are questions we need to ask as we explore the possibilities of a modular build structure.
          Hide
          Dennis Reedy added a comment -

          So #1, #3 and #2 seems to be the priority?

          Publishing artifacts to a Maven repository should be no problem with Gradle. Disclaimer: I am learning Gradle as this goes along, so this should be fun

          As far as moving forward with Maven and Gradle, I'd rather just choose one. My suggestion is Gradle.

          Pros:

          • It handles multi-module projects better
          • Very powerful and flexible
          • It is Groovy based, so we can program our build scripts, plus get away from XML

          Cons:

          • Still early in it's process, not mature
          Show
          Dennis Reedy added a comment - So #1, #3 and #2 seems to be the priority? Publishing artifacts to a Maven repository should be no problem with Gradle. Disclaimer: I am learning Gradle as this goes along, so this should be fun As far as moving forward with Maven and Gradle, I'd rather just choose one. My suggestion is Gradle. Pros: It handles multi-module projects better Very powerful and flexible It is Groovy based, so we can program our build scripts, plus get away from XML Cons: Still early in it's process, not mature
          Hide
          Tom Hobbs added a comment -

          I don't think that the package rename was a step to far. The only issue with merging the two tasks is making this live is now a much larger issue with regards to River users. The next release after River-300 makes it into the trunk will obviously contain some pretty serious changes as far as they're concerned.

          The next steps seem sensible. Choosing Gradle or Maven should probably be #1, unless you're happing bringing them both along at the same time and deferring the decision? I've never had a good experience trying to force Maven to do something it doesn't want to do, so maybe dropping that in favour of Gradle would be easier all round? Can something built with Gradle still publish artifacts to Maven repos?

          Tasks 2 and 3 could probably be done in either order or concurrently. I'm particularly interested to see how how the QA and JTReg tests will behave and can be segregated.

          Show
          Tom Hobbs added a comment - I don't think that the package rename was a step to far. The only issue with merging the two tasks is making this live is now a much larger issue with regards to River users. The next release after River-300 makes it into the trunk will obviously contain some pretty serious changes as far as they're concerned. The next steps seem sensible. Choosing Gradle or Maven should probably be #1, unless you're happing bringing them both along at the same time and deferring the decision? I've never had a good experience trying to force Maven to do something it doesn't want to do, so maybe dropping that in favour of Gradle would be easier all round? Can something built with Gradle still publish artifacts to Maven repos? Tasks 2 and 3 could probably be done in either order or concurrently. I'm particularly interested to see how how the QA and JTReg tests will behave and can be segregated.
          Hide
          Dennis Reedy added a comment -

          Should we rename this issue to: Introduce modularized River project?

          Show
          Dennis Reedy added a comment - Should we rename this issue to: Introduce modularized River project?
          Hide
          Dennis Reedy added a comment -

          I agree with making sure we dont pile on too much for this issue. IMO this issue should be scoped to provide (as much as possible) a structured and modular distribution of the source code that results in the creation of artifacts that are equivalent (again: as much as possible) jars as found in the current project build.

          I had taken the opportunity to perform the namespace replacement of com.sun.jini.* to org.apache.river.*, perhaps that was too far reaching, but it made sense to me at the time.

          Possible next steps here may be:

          1. Address the issue for jsk-resources.jar and jsk-policy.jar
          2. Provide aggregation tasks for javadoc
          3. Add QA project (or at least some of the QA project) execution into the lifecycle of building the project
          4. Perhaps this should be item #0, decide whether we want to work with Maven or Gradle. Gradle may have benefits for #1 above, where we could create multiple artifacts from a single module. While this is doable with Maven, its not exactly straightforward.

          Show
          Dennis Reedy added a comment - I agree with making sure we dont pile on too much for this issue. IMO this issue should be scoped to provide (as much as possible) a structured and modular distribution of the source code that results in the creation of artifacts that are equivalent (again: as much as possible) jars as found in the current project build. I had taken the opportunity to perform the namespace replacement of com.sun.jini.* to org.apache.river.*, perhaps that was too far reaching, but it made sense to me at the time. Possible next steps here may be: 1. Address the issue for jsk-resources.jar and jsk-policy.jar 2. Provide aggregation tasks for javadoc 3. Add QA project (or at least some of the QA project) execution into the lifecycle of building the project 4. Perhaps this should be item #0, decide whether we want to work with Maven or Gradle. Gradle may have benefits for #1 above, where we could create multiple artifacts from a single module. While this is doable with Maven, its not exactly straightforward.
          Hide
          Tom Hobbs added a comment -

          A separate module sounds like a good idea. Am I right in thinking that will help us when supporting multiple JDK versions?

          The not requiring preferred class loading sounds like a very good idea. Can be done after River-300 though? I'm just concious of the scope of River-300 getting to large. I'm tempted to say let's sort the build system (one way or another) and define the modules (including Service API). Then we can apply the gravy afterwards.

          Show
          Tom Hobbs added a comment - A separate module sounds like a good idea. Am I right in thinking that will help us when supporting multiple JDK versions? The not requiring preferred class loading sounds like a very good idea. Can be done after River-300 though? I'm just concious of the scope of River-300 getting to large. I'm tempted to say let's sort the build system (one way or another) and define the modules (including Service API). Then we can apply the gravy afterwards.
          Hide
          Peter Firmstone added a comment -

          LookupLocatorDiscovery is imported by LookupLocator, but only for javadoc.

          However as I mentioned earlier, LookupLocatorDiscovery is a potential unifying api class.

          Show
          Peter Firmstone added a comment - LookupLocatorDiscovery is imported by LookupLocator, but only for javadoc. However as I mentioned earlier, LookupLocatorDiscovery is a potential unifying api class.
          Hide
          Peter Firmstone added a comment -

          This might be an opportune time to consider what we need in the Platform, we might even consider making a separate module for Service API, I've noticed that some Service API is packaged in jsk-lib.jar

          The interesting thing about how Jini has evolved is the handling of namespaces and ClassLoading.

          Preferred class loading was provided as a solution to class resolution and visibility for ClassLoaders, some issues remain with this strategy, as detailed in Mike Warres class loading paper. https://issues.apache.org/jira/secure/attachment/12413650/Java+Classloader+issues+relating+to+Jini+smli_tr-2006-149.pdf

          Preferred class loading presents the developer with additional configuration, which the developer may not always have correctly configured.

          The reason preferred class loading exists is to resolve classes from the proxy namespace or some other namespace (where namespace can be interchanged with ClassLoader), when those classes might ordinarily be resolved by the application class loader, with local libraries or classes at the client, that may cause version conflicts and codebase annotation loss.

          So we are now presented with an opportunity, to design a platform, that we will completely support in a backward compatible fashion, thus not requiring preferred class loading configuration by default. By providing standard practices for developers to follow, we can make deployment simpler.

          It is therefore in our interests to keep the platform minimal, but to also include unifying classes like LookupLocatorDiscovery which clients can utilise as a standard api for multiple forms of discovery (requires some additional work on our part).

          So I propose we define what we want in the platform, then run a ClassDep analysis to discover what other classes need to be included.

          Show
          Peter Firmstone added a comment - This might be an opportune time to consider what we need in the Platform, we might even consider making a separate module for Service API, I've noticed that some Service API is packaged in jsk-lib.jar The interesting thing about how Jini has evolved is the handling of namespaces and ClassLoading. Preferred class loading was provided as a solution to class resolution and visibility for ClassLoaders, some issues remain with this strategy, as detailed in Mike Warres class loading paper. https://issues.apache.org/jira/secure/attachment/12413650/Java+Classloader+issues+relating+to+Jini+smli_tr-2006-149.pdf Preferred class loading presents the developer with additional configuration, which the developer may not always have correctly configured. The reason preferred class loading exists is to resolve classes from the proxy namespace or some other namespace (where namespace can be interchanged with ClassLoader), when those classes might ordinarily be resolved by the application class loader, with local libraries or classes at the client, that may cause version conflicts and codebase annotation loss. So we are now presented with an opportunity, to design a platform, that we will completely support in a backward compatible fashion, thus not requiring preferred class loading configuration by default. By providing standard practices for developers to follow, we can make deployment simpler. It is therefore in our interests to keep the platform minimal, but to also include unifying classes like LookupLocatorDiscovery which clients can utilise as a standard api for multiple forms of discovery (requires some additional work on our part). So I propose we define what we want in the platform, then run a ClassDep analysis to discover what other classes need to be included.
          Dennis Reedy made changes -
          Attachment river-modularization-overview.pdf [ 12468650 ]
          Hide
          Dennis Reedy added a comment -

          With regard to including the following classes into river-platform:

          DiscoveryEvent
          DiscoveryListener
          DiscoverLocatorManagement
          DiscoveryManagement
          LookupLocatorDiscovery

          The net.jini.core.discoveryLookupLocator imports net.jini.discovery.LookupLocatorDiscovery. If net.jini.discovery.LookupLocatorDiscovery is not part of the river-platform, the river-platform cannot build. The inclusion of the other classes in question is due to this dependency as well, so the inclusion was definitely deliberate.

          Show
          Dennis Reedy added a comment - With regard to including the following classes into river-platform: DiscoveryEvent DiscoveryListener DiscoverLocatorManagement DiscoveryManagement LookupLocatorDiscovery The net.jini.core.discoveryLookupLocator imports net.jini.discovery.LookupLocatorDiscovery. If net.jini.discovery.LookupLocatorDiscovery is not part of the river-platform, the river-platform cannot build. The inclusion of the other classes in question is due to this dependency as well, so the inclusion was definitely deliberate.
          Dennis Reedy made changes -
          Attachment river-modularization-overview.odt [ 12468648 ]
          Dennis Reedy made changes -
          Comment [ The organization of the project is structured as follows:

          apache-river \
              |- river-libs (*)
                  |- river-dl
                  |- river-lib

              |- river-services (*) \
                  |- reggie (*) \
                      |- reggie-proxy
                      |- reggie-service

                  |- outrigger (*) \
                      |- outrigger-proxy
                      |- outrigger-service

              |- river-platform
              |- river-start

          At this time, each module produces one artifact (the directories with a '*' do not produce artifacts, they are used for source code organization). The produced name of the artifact is the same as the name of the module, with the addition of the version number of the project.

          Going forward we may find that we need to provide additional processing options in river-platform to produce equivalent jsk-resources and jsk-policy.jar artifacts.

          All Java source code is located in accepted standard locations

          src/main/java

          Groovy source would similarly be located in

          src/main/groovy

          All test code for each module is encouraged to be located in

          src/test/java

          As for determining what classes go in what module, the approach is simply to look at what classes are in what jar file and organize the modules accordingly. Key to the modularization was to remove reliance on classdepandjar.

          It should be simple to see how additional services can be added to this structure by following the convention of:

          <service> \
              | - <service>-proxy
              | - <service>-service

          More information on the convention used for this project can be found here: http://www.rio-project.org/conventions.html

          Building
          --------

          If using Maven, well, you use Maven. If you are not familiar with Maven you want to start here http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html

          Running either

          > mvn install

          Or

          > mvn package

          The distribution is placed into

          dist/target/apache-river-2.2-SNAPSHOT

          If using Gradle,

          > gradle build
          > gradle -q dist

          The distribution is placed into

          distribution/

          The produced jars for either distribution are as follows:

          lib/

          outrigger-service-2.2-SNAPSHOT.jar
          outrigger-snaplogstore-2.2-SNAPSHOT.jar
          reggie-service-2.2-SNAPSHOT.jar
          river-lib-2.2-SNAPSHOT.jar
          river-platform-2.2-SNAPSHOT.jar
          river-start-2.2-SNAPSHOT.jar

          lib-dl/
          -------
          outrigger-proxy-2.2-SNAPSHOT.jar
          reggie-proxy-2.2-SNAPSHOT.jar
          river-dl-2.2-SNAPSHOT.jar

          The produced archives also have converted the com.sun.jini namespace to the org.apache.river namespace.

          Testing
          -------
          Right now there are no testcases included in the contributions. Ideally, we would move forward with adding testcases to each constituent module. That way as each module is assembled, it will run through it's testcases in an automated fashion.

          The current testing framework can be easily added to the existing build setup in the same way as it's run today, perhaps tied to a specific lifecycle using Maven), or to a specific task (using Gradle). The latter may be more accepted since Gradle has strong Ant ties and semantics. ]
          Peter Firmstone made changes -
          Link This issue is related to RIVER-261 [ RIVER-261 ]
          Hide
          Peter Firmstone added a comment -

          I'm going to assume for now that the reasons the classes have been moved into platform from lib was perhaps due to time, we can move classes back in later. For now I'm just going to stick with the dependency structure of the existing build, but without class file duplication, as Dennis has done so far.

          LookupLocatorDiscovery, looks like a good candidate to be moved into the platform, perhaps we can discuss it at length later.

          Show
          Peter Firmstone added a comment - I'm going to assume for now that the reasons the classes have been moved into platform from lib was perhaps due to time, we can move classes back in later. For now I'm just going to stick with the dependency structure of the existing build, but without class file duplication, as Dennis has done so far. LookupLocatorDiscovery, looks like a good candidate to be moved into the platform, perhaps we can discuss it at length later.
          Hide
          Peter Firmstone added a comment -

          I've noticed classes from other packages that are included in platform rather than lib also.

          From packages:
          org.apache.river.
          config
          constants
          start
          thread

          Show
          Peter Firmstone added a comment - I've noticed classes from other packages that are included in platform rather than lib also. From packages: org.apache.river. config constants start thread
          Hide
          Peter Firmstone added a comment -

          Dennis, I've noticed that you've included the following files from jsk-lib in river-platform from the net.jini.discovery package, I was wondering if this is deliberate or accidental?

          DiscoveryEvent
          DiscoveryListener
          DiscoverLocatorManagement
          DiscoveryManagement
          LookupLocatorDiscovery

          Cheers,

          Peter.

          Show
          Peter Firmstone added a comment - Dennis, I've noticed that you've included the following files from jsk-lib in river-platform from the net.jini.discovery package, I was wondering if this is deliberate or accidental? DiscoveryEvent DiscoveryListener DiscoverLocatorManagement DiscoveryManagement LookupLocatorDiscovery Cheers, Peter.
          Hide
          Peter Firmstone added a comment -

          In the existing build jsk-policy.jar is an optional file, it duplicates class files from jsk-platform.jar

          Since jsk-policy.jar is loaded by the ext class loader, it is actually a parent ClassLoader of the application ClassLoader, which means that classes in jsk-platform.jar cannot be seen by jsk-policy.jar classes, therefore, it would seem to make sense to include the duplicated classes in the policy module, and have the platform module depend on the policy module.

          Does this make sense? How will this affect modular systems? The policy module will need to be loaded into the java extension class loader, this can be done by way of a java command argument or by using the jre ext directory.

          Show
          Peter Firmstone added a comment - In the existing build jsk-policy.jar is an optional file, it duplicates class files from jsk-platform.jar Since jsk-policy.jar is loaded by the ext class loader, it is actually a parent ClassLoader of the application ClassLoader, which means that classes in jsk-platform.jar cannot be seen by jsk-policy.jar classes, therefore, it would seem to make sense to include the duplicated classes in the policy module, and have the platform module depend on the policy module. Does this make sense? How will this affect modular systems? The policy module will need to be loaded into the java extension class loader, this can be done by way of a java command argument or by using the jre ext directory.
          Hide
          Peter Firmstone added a comment -

          Since the Gradle and Maven builds share the same source tree and because the build scripts are small in any case, is it practical to include both to begin with? Or should we choose one over the other?

          I've been adding the Gradle build to skunk, with the knowledge that this can be changed easily to Maven if need be.

          Show
          Peter Firmstone added a comment - Since the Gradle and Maven builds share the same source tree and because the build scripts are small in any case, is it practical to include both to begin with? Or should we choose one over the other? I've been adding the Gradle build to skunk, with the knowledge that this can be changed easily to Maven if need be.
          Hide
          Peter Firmstone added a comment -

          Over the weekend, I'll setup an area in skunk, then copy the source files from trunk to preserve svn history, then add the new modular build files.

          I've downloaded and built the maven zip. I've downloaded Gradle, but haven't yet built the gradle zip.

          Cheers,

          Peter

          Show
          Peter Firmstone added a comment - Over the weekend, I'll setup an area in skunk, then copy the source files from trunk to preserve svn history, then add the new modular build files. I've downloaded and built the maven zip. I've downloaded Gradle, but haven't yet built the gradle zip. Cheers, Peter
          Dennis Reedy made changes -
          Field Original Value New Value
          Attachment apache-river-gradle.zip [ 12467565 ]
          Attachment apache-river-maven.zip [ 12467566 ]
          Hide
          Dennis Reedy added a comment -

          I have attached 2 zips to this issue. Both archives use the same codebase, and have a limited set of the River source included. The approach taken was to break out River into a multi-module project, with each module responsible for producing a single jar file.

          For the Maven project, run:

          > mvn package

          The distribution is placed into

          dist/target/apache-river-2.2-SNAPSHOT

          For the Gradle project, run:

          > gradle build
          > gradle -q dist

          The distribution is placed into

          distribution/

          The produced jars are as follows:

          lib/


          outrigger-service-2.2-SNAPSHOT.jar
          outrigger-snaplogstore-2.2-SNAPSHOT.jar
          reggie-service-2.2-SNAPSHOT.jar
          river-lib-2.2-SNAPSHOT.jar
          river-platform-2.2-SNAPSHOT.jar
          river-start-2.2-SNAPSHOT.jar

          lib-dl/
          -------
          outrigger-proxy-2.2-SNAPSHOT.jar
          reggie-proxy-2.2-SNAPSHOT.jar
          river-dl-2.2-SNAPSHOT.jar

          The attached archives also have converted the com.sun.jini namespace to the org.apache.river namespace.

          Obviously there is a lot of work to do with this effort. The attachments are meant to show how the project may want to consider a modularization of the River codebase using either Maven or Gradle.

          Show
          Dennis Reedy added a comment - I have attached 2 zips to this issue. Both archives use the same codebase, and have a limited set of the River source included. The approach taken was to break out River into a multi-module project, with each module responsible for producing a single jar file. For the Maven project, run: > mvn package The distribution is placed into dist/target/apache-river-2.2-SNAPSHOT For the Gradle project, run: > gradle build > gradle -q dist The distribution is placed into distribution/ The produced jars are as follows: lib/ outrigger-service-2.2-SNAPSHOT.jar outrigger-snaplogstore-2.2-SNAPSHOT.jar reggie-service-2.2-SNAPSHOT.jar river-lib-2.2-SNAPSHOT.jar river-platform-2.2-SNAPSHOT.jar river-start-2.2-SNAPSHOT.jar lib-dl/ ------- outrigger-proxy-2.2-SNAPSHOT.jar reggie-proxy-2.2-SNAPSHOT.jar river-dl-2.2-SNAPSHOT.jar The attached archives also have converted the com.sun.jini namespace to the org.apache.river namespace. Obviously there is a lot of work to do with this effort. The attachments are meant to show how the project may want to consider a modularization of the River codebase using either Maven or Gradle.
          Hide
          Wade Chandler added a comment -

          Jools, have you began working on the issue? Is there anything which I can help you with?

          Show
          Wade Chandler added a comment - Jools, have you began working on the issue? Is there anything which I can help you with?
          Jools Enticknap created issue -

            People

            • Assignee:
              Unassigned
              Reporter:
              Jools Enticknap
            • Votes:
              1 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:

                Time Tracking

                Estimated:
                Original Estimate - 28m
                28m
                Remaining:
                Remaining Estimate - 28m
                28m
                Logged:
                Time Spent - Not Specified
                Not Specified

                  Development