You are viewing a plain text version of this content. The canonical link for it is here.
Posted to proton@qpid.apache.org by Hiram Chirino <hi...@hiramchirino.com> on 2013/08/01 18:50:30 UTC

proton-j API factory simplification.

Hi folks,

I was just thinking perhaps we should simplify all the factory stuff
in the proton API.  Mostly get rid of it.  Don't think it's really
needed.  Mainly I think we need to make Proton an interface and let
folks assign it the desired implementation.  Something like:

Proton p = new ProtonJ();

or

Proton p = new ProtonC();

where ProtonJ and ProtonC are in the respective implementation jars.

if folks really want to make it configurable, they can easily build an
if statement to pick the impl that they desire.


-- 
Hiram Chirino

Engineering | Red Hat, Inc.

hchirino@redhat.com | fusesource.com | redhat.com

skype: hiramchirino | twitter: @hiramchirino

blog: Hiram Chirino's Bit Mojo

Re: proton-j API factory simplification.

Posted by Hiram Chirino <hi...@hiramchirino.com>.
Correct:  'I don't think ProtonJ and ProtonC should reside in the
proton-api.jar'

On Fri, Aug 2, 2013 at 8:35 AM, Rajith Attapattu <ra...@gmail.com> wrote:
>>
>> So, I'd be in favour of Hiram's proposal if ProtonJ and ProtonC reside in
>> proton-api.jar.  This would be very easy to do, e.g.
>>
>>
> I don't think ProtonJ and ProtonC should reside in the proton-api.jar
> And I don't think thats what Hiram suggested either (pls correct me if I
> have misunderstood).
>
> Only the Proton interface and supported interfaces needs to be there in
> proton-api.jar.
> ProtonJ, ProtonC, or any other implementation will be in the respective
> implementation jars.
>
> Apart from testing, I doubt most people will want to switch between
> implementations the way we have them now.
> For most it would be an informed decision of choosing a particular
> implementation after weighing the pros and cons of it.
>
> Rajith



-- 
Hiram Chirino

Engineering | Red Hat, Inc.

hchirino@redhat.com | fusesource.com | redhat.com

skype: hiramchirino | twitter: @hiramchirino

blog: Hiram Chirino's Bit Mojo

Re: proton-j API factory simplification.

Posted by Rajith Attapattu <ra...@gmail.com>.
>
> So, I'd be in favour of Hiram's proposal if ProtonJ and ProtonC reside in
> proton-api.jar.  This would be very easy to do, e.g.
>
>
I don't think ProtonJ and ProtonC should reside in the proton-api.jar
And I don't think thats what Hiram suggested either (pls correct me if I
have misunderstood).

Only the Proton interface and supported interfaces needs to be there in
proton-api.jar.
ProtonJ, ProtonC, or any other implementation will be in the respective
implementation jars.

Apart from testing, I doubt most people will want to switch between
implementations the way we have them now.
For most it would be an informed decision of choosing a particular
implementation after weighing the pros and cons of it.

Rajith

Re: proton-j API factory simplification.

Posted by Rafael Schloming <rh...@alum.mit.edu>.
Say you have a user who is intentionally dependent on the ProtonJ
implementation (e.g. hiram). He now needs to write code that looks like
this:

    Connection conn = discoveryMechanism(...);
    ProtonJConnection jconn = (ProtonJConnection) conn;

This is basically analogous to asking all collections users to dynamically
choose between ArrayList and LinkedList and then cast to the one that their
implementation actually requires:

    List list = discoveryMechanism(...);
    ArrayList arrayList = (ArrayList) list;

So by forcing the discovery and cast onto the user you are preventing them
from actually declaring their intention to require a specific
implementation to the compiler. Obviously this would be a ridiculous thing
to require for something like collections. Now of course whether our
situation is entirely analogous to collections is really dependent on some
of the questions I asked in the other thread about packaging/organization.
If intentionally depending on a specific implementation is a legitimate
thing for a user to do, then not only does the API need an entry point for
users to get started with, but each implementation also needs one, and the
pattern hiram suggests seems like an exceptionally good fit as it gives you
a very clear entry points for all three of ProtonJ, ProtonC, and generic
Proton.

On the other hand if our intentions are to use interfaces in more of a
JMS/JDBC style manner where the interface/impl split is really an
interface/*vendor impl* split (where by vendor I mean any independent
implementation), then that is a whole different story, and a discovery
mechanism makes more sense, although it doesn't really preclude having
simple and concrete ProtonJ/ProtonC entry points as hiram suggests.

And there is of course a third option which is that we don't want our users
to actually even need to be aware there are multiple implementations. We
only have them for our internal testing purposes.

I think each one of these options suggest different API choices, and right
now we aren't really following any one of them particularly well. We have
public portions of proton-j which would suggest that you should be allowed
to choose to depend on it. We have a very complex factory system which
would suggest we're going for something like multiple vender-style
implementations, and we certainly aren't hiding the fact that there are
multiple implementations, but we've provided no clear guidance on why a
user might choose one over the other.

--Rafael

On Fri, Aug 2, 2013 at 10:55 AM, Rob Godfrey <ro...@gmail.com>wrote:

> Given the Proton class doesn't require the user to know which
> implementation they are using (but allows them to explicitly ask for a
> particular implementation type if they so desire) I'm a little confused how
> adding the requirement for the user to instantiate an implementation
> specific class actually helps the user.  Am I missing something?  There
> really is no need for a user to know about factories, etc...
>
> -- Rob
>
>
> On 2 August 2013 15:13, Rafael Schloming <rh...@alum.mit.edu> wrote:
>
> > On Fri, Aug 2, 2013 at 4:44 AM, Phil Harvey <phil@philharveyonline.com
> > >wrote:
> >
> > > I agree that o.a.q.p.Proton is, overall, an improvement.  I was partly
> > > responsible for creating the ProtonFactoryLoader and XXXFactory
> classes,
> > > and acknowledge that they make life too hard for the user.
> > >
> > > This was a result of trying to meet the following design goals:
> > > 1. User code should not need to have a compile-time dependency on any
> > > proton-c/j/jni classes.  Given our current separation of the proton-api
> > > from the proton-impl/proton-jni modules, it means user code should only
> > > depend on proton-api at compile-time.
> > > 2. Classes from the various "top level packages", such as engine,
> > messenger
> > > etc, should be kept separate unless they really need to be together.
> > >
> > > I still believe in goal 1 (though this will be discussed at greater
> > length
> > > on the related thread [1]), but am relaxed about item 2.
> > >
> >
> > Thanks for describing the goals, it's helpful to have them written down.
> I
> > personally don't feel that the Proton class is violating (2) in an
> > important way so long as engine and messenger remain otherwise
> unentwined.
> >
> > I generally agree with (1) also, however I think it could use some
> further
> > refinement. At the root of (1) is the desire to make it clear and obvious
> > to developers if/when they are depending on the characteristics of a
> given
> > implementation rather than on a more abstracted interface. Probably the
> > most common example of this sort of thing within Java would be typical
> > collections usage of interface/impl splits, e.g.:
> >
> >     List foo = new ArrayList();
> >     ArrayList bar = new ArrayList();
> >     LinkedList baz = new LinkedList();
> >
> > The suggested pattern for the Proton class would be following this
> pattern
> > exactly:
> >
> >     Proton p = new ProtonJ();
> >     ProtonJ pj = new ProtonJ();
> >     ProtonC pc = new ProtonC();
> >
> > Now this pattern of course doesn't really speak to classpaths at all. The
> > classpath issue is really entirely orthogonal to the interface/impl
> > distinction. Right now we have separate classpaths, but a muddled
> > interface/impl distinction since the impl jar adds new interfaces into
> > packages belonging to the API jar, and the API jar has stuff in it that
> is
> > really part of a specific impl. Likewise, you can have a clear
> > interface/impl distinctions within a single jar as is the case with java
> > collections.
> >
> > I'd argue that the classpath thing is really a distinct goal/requirement
> > and is really more about a discovery mechanism for independent or third
> > party implementations. I don't personally feel that this is a necessary
> > requirement for us at this point, but I'm fairly relaxed if other people
> > would like to support it.
> >
> > Given the above refinement of (1) into (1a) interface/impl split and (1b)
> > independently implementable API, I would find it a bit odd to put the
> > ProtonJ/ProtonC classes into the API package since that would introduce a
> > dependency from the API package back to those impls (even if its only a
> > runtime dependency) and would effectively give those impls an elevated
> > position which in some sense is fine, but also seems contrary to the
> > independently implementable notion in the first place. It seems like what
> > you'd want in the API package is purely a generic discovery mechanism
> that
> > would work for any implementation.
> >
> > As I said above, I don't feel like such a discovery mechanism is really a
> > requirement for us right now. I think actually having a complicated
> > discovery/factory pattern is in some ways detrimental as it creates a
> > barrier to entry for all users when most don't care about the flexibility
> > it offers (at least right now) and if they do care about that flexibility
> > it is easy enough for them to build their own. In fact modulo exception
> > handling it is really just one extra line of code:
> >
> >     Class impl = Class.forName(System.getProperty("blah"));
> >     Proton p = (Proton) impl.newInstance();
> >
> > So I'd personally say go for the simple interface/impl split pattern that
> > everyone knows and is used to and don't worry about a generic discovery
> > mechanism until we actually have enough implementations for it to be
> > warranted.
> >
> > --Rafael
> >
>

Re: proton-j API factory simplification.

Posted by Hiram Chirino <hi...@hiramchirino.com>.
Honestly I don't see the need for the newInstance() method.  If the
user wants his code to stay decoupled from the implementation he can
use an IoC framework to inject the appropriate Proton implementation.

The other apps that don't have that requirement will probably be happy
just doing the simple call:
Proton proton = new ProtonC();

I just worry that we are adding factory complexity to the Proton api which:

 1) Wont work in all Java environments like OSGi
 2) Has been solved better by IoC frameworks like CDI, Spring, Guice,
BluePrint, and (if squint right) JNDI.



On Fri, Aug 9, 2013 at 11:42 AM, Phil Harvey <ph...@philharveyonline.com> wrote:
> I had assumed that application code having a compile-time dependency on
> proton-j-impl (or theoretically on proton-jni) was anathema to proton's
> interchangeable proton-c/proton-j philosophy.  However, the consensus seems
> to be that this is acceptable.  I'm ok with that.
>
> In this case, I would be happy for us to put the proposed ProtonC and
> ProtonJ classes in the proton-jni and proton-j-impl modules respectively.
>
> I therefore expect we'll have something like this:
>
> === In proton-api ===
> package o.a.q.proton;
>
> public abstract class Proton
> {
>   /** dynamically chooses whether to return a ProtonJ or a ProtonC */
>   public static Proton newInstance();
>
>   public Connection connection()
>   { ... }
> }
>
>
> === In proton-j-impl ===
> package o.a.q.proton.*impl*;
>
> public class ProtonJ extends Proton
> {
>   public ProtonJ()
>   { }
>
>   @*Override*
>   public *ProtonJ*Connection connection()
>   { ... }
> }
>
> Most applications would call Proton.newInstance() and would therefore omit
> proton-j-impl (or proton-jni) from their compile-time classpath.  Whichever
> of ProtonJ and ProtonC is returned at run-time, these applications would
> experience a fully functional Proton (I struggle for a proper definition of
> "fully functional", but I think we can rely on common sense here).
>
> The minority of applications that wish to use implementation-specific
> classes would directly construct a new ProtonJ/ProtonC.
>
> We would document the intended usage, and package-scope (and possibly also
> streamline) the XXXFactory and ProtonFactoryLoader classes to reduce our
> users' confusion.
>
> I agree that there are outstanding issues around Java package design, such
> as the overlapping namespace of proton-api and proton-j-impl.  Also, the
> need to properly define the public API of proton-j-impl becomes more
> pressing if we're going to expect people to compile against it.  I'm not
> sure what the right answers to these questions are, but propose that we
> resolve this Proton/ProtonJ/ProtonC stuff first.
>
>
> Phil
>
>
>
> On 8 August 2013 17:45, Hiram Chirino <hi...@hiramchirino.com> wrote:
>
>> You guys also need to keep in mind that doing dynamic loading of
>> implementations classes may need to be implemented differently based
>> on the container that the app is running in.  A good example is OSGi.
>> The way factories are currently implemented would probably not work
>> there.  So it's best to avoid getting into the factory business to
>> begin with.
>>
>>
>> On Fri, Aug 2, 2013 at 10:55 AM, Rob Godfrey <ro...@gmail.com>
>> wrote:
>> > Given the Proton class doesn't require the user to know which
>> > implementation they are using (but allows them to explicitly ask for a
>> > particular implementation type if they so desire) I'm a little confused
>> how
>> > adding the requirement for the user to instantiate an implementation
>> > specific class actually helps the user.  Am I missing something?  There
>> > really is no need for a user to know about factories, etc...
>> >
>> > -- Rob
>> >
>> >
>> > On 2 August 2013 15:13, Rafael Schloming <rh...@alum.mit.edu> wrote:
>> >
>> >> On Fri, Aug 2, 2013 at 4:44 AM, Phil Harvey <phil@philharveyonline.com
>> >> >wrote:
>> >>
>> >> > I agree that o.a.q.p.Proton is, overall, an improvement.  I was partly
>> >> > responsible for creating the ProtonFactoryLoader and XXXFactory
>> classes,
>> >> > and acknowledge that they make life too hard for the user.
>> >> >
>> >> > This was a result of trying to meet the following design goals:
>> >> > 1. User code should not need to have a compile-time dependency on any
>> >> > proton-c/j/jni classes.  Given our current separation of the
>> proton-api
>> >> > from the proton-impl/proton-jni modules, it means user code should
>> only
>> >> > depend on proton-api at compile-time.
>> >> > 2. Classes from the various "top level packages", such as engine,
>> >> messenger
>> >> > etc, should be kept separate unless they really need to be together.
>> >> >
>> >> > I still believe in goal 1 (though this will be discussed at greater
>> >> length
>> >> > on the related thread [1]), but am relaxed about item 2.
>> >> >
>> >>
>> >> Thanks for describing the goals, it's helpful to have them written
>> down. I
>> >> personally don't feel that the Proton class is violating (2) in an
>> >> important way so long as engine and messenger remain otherwise
>> unentwined.
>> >>
>> >> I generally agree with (1) also, however I think it could use some
>> further
>> >> refinement. At the root of (1) is the desire to make it clear and
>> obvious
>> >> to developers if/when they are depending on the characteristics of a
>> given
>> >> implementation rather than on a more abstracted interface. Probably the
>> >> most common example of this sort of thing within Java would be typical
>> >> collections usage of interface/impl splits, e.g.:
>> >>
>> >>     List foo = new ArrayList();
>> >>     ArrayList bar = new ArrayList();
>> >>     LinkedList baz = new LinkedList();
>> >>
>> >> The suggested pattern for the Proton class would be following this
>> pattern
>> >> exactly:
>> >>
>> >>     Proton p = new ProtonJ();
>> >>     ProtonJ pj = new ProtonJ();
>> >>     ProtonC pc = new ProtonC();
>> >>
>> >> Now this pattern of course doesn't really speak to classpaths at all.
>> The
>> >> classpath issue is really entirely orthogonal to the interface/impl
>> >> distinction. Right now we have separate classpaths, but a muddled
>> >> interface/impl distinction since the impl jar adds new interfaces into
>> >> packages belonging to the API jar, and the API jar has stuff in it that
>> is
>> >> really part of a specific impl. Likewise, you can have a clear
>> >> interface/impl distinctions within a single jar as is the case with java
>> >> collections.
>> >>
>> >> I'd argue that the classpath thing is really a distinct goal/requirement
>> >> and is really more about a discovery mechanism for independent or third
>> >> party implementations. I don't personally feel that this is a necessary
>> >> requirement for us at this point, but I'm fairly relaxed if other people
>> >> would like to support it.
>> >>
>> >> Given the above refinement of (1) into (1a) interface/impl split and
>> (1b)
>> >> independently implementable API, I would find it a bit odd to put the
>> >> ProtonJ/ProtonC classes into the API package since that would introduce
>> a
>> >> dependency from the API package back to those impls (even if its only a
>> >> runtime dependency) and would effectively give those impls an elevated
>> >> position which in some sense is fine, but also seems contrary to the
>> >> independently implementable notion in the first place. It seems like
>> what
>> >> you'd want in the API package is purely a generic discovery mechanism
>> that
>> >> would work for any implementation.
>> >>
>> >> As I said above, I don't feel like such a discovery mechanism is really
>> a
>> >> requirement for us right now. I think actually having a complicated
>> >> discovery/factory pattern is in some ways detrimental as it creates a
>> >> barrier to entry for all users when most don't care about the
>> flexibility
>> >> it offers (at least right now) and if they do care about that
>> flexibility
>> >> it is easy enough for them to build their own. In fact modulo exception
>> >> handling it is really just one extra line of code:
>> >>
>> >>     Class impl = Class.forName(System.getProperty("blah"));
>> >>     Proton p = (Proton) impl.newInstance();
>> >>
>> >> So I'd personally say go for the simple interface/impl split pattern
>> that
>> >> everyone knows and is used to and don't worry about a generic discovery
>> >> mechanism until we actually have enough implementations for it to be
>> >> warranted.
>> >>
>> >> --Rafael
>> >>
>>
>>
>>
>> --
>> Hiram Chirino
>>
>> Engineering | Red Hat, Inc.
>>
>> hchirino@redhat.com | fusesource.com | redhat.com
>>
>> skype: hiramchirino | twitter: @hiramchirino
>>
>> blog: Hiram Chirino's Bit Mojo
>>



-- 
Hiram Chirino

Engineering | Red Hat, Inc.

hchirino@redhat.com | fusesource.com | redhat.com

skype: hiramchirino | twitter: @hiramchirino

blog: Hiram Chirino's Bit Mojo

Re: proton-j API factory simplification.

Posted by Phil Harvey <ph...@philharveyonline.com>.
I had assumed that application code having a compile-time dependency on
proton-j-impl (or theoretically on proton-jni) was anathema to proton's
interchangeable proton-c/proton-j philosophy.  However, the consensus seems
to be that this is acceptable.  I'm ok with that.

In this case, I would be happy for us to put the proposed ProtonC and
ProtonJ classes in the proton-jni and proton-j-impl modules respectively.

I therefore expect we'll have something like this:

=== In proton-api ===
package o.a.q.proton;

public abstract class Proton
{
  /** dynamically chooses whether to return a ProtonJ or a ProtonC */
  public static Proton newInstance();

  public Connection connection()
  { ... }
}


=== In proton-j-impl ===
package o.a.q.proton.*impl*;

public class ProtonJ extends Proton
{
  public ProtonJ()
  { }

  @*Override*
  public *ProtonJ*Connection connection()
  { ... }
}

Most applications would call Proton.newInstance() and would therefore omit
proton-j-impl (or proton-jni) from their compile-time classpath.  Whichever
of ProtonJ and ProtonC is returned at run-time, these applications would
experience a fully functional Proton (I struggle for a proper definition of
"fully functional", but I think we can rely on common sense here).

The minority of applications that wish to use implementation-specific
classes would directly construct a new ProtonJ/ProtonC.

We would document the intended usage, and package-scope (and possibly also
streamline) the XXXFactory and ProtonFactoryLoader classes to reduce our
users' confusion.

I agree that there are outstanding issues around Java package design, such
as the overlapping namespace of proton-api and proton-j-impl.  Also, the
need to properly define the public API of proton-j-impl becomes more
pressing if we're going to expect people to compile against it.  I'm not
sure what the right answers to these questions are, but propose that we
resolve this Proton/ProtonJ/ProtonC stuff first.


Phil



On 8 August 2013 17:45, Hiram Chirino <hi...@hiramchirino.com> wrote:

> You guys also need to keep in mind that doing dynamic loading of
> implementations classes may need to be implemented differently based
> on the container that the app is running in.  A good example is OSGi.
> The way factories are currently implemented would probably not work
> there.  So it's best to avoid getting into the factory business to
> begin with.
>
>
> On Fri, Aug 2, 2013 at 10:55 AM, Rob Godfrey <ro...@gmail.com>
> wrote:
> > Given the Proton class doesn't require the user to know which
> > implementation they are using (but allows them to explicitly ask for a
> > particular implementation type if they so desire) I'm a little confused
> how
> > adding the requirement for the user to instantiate an implementation
> > specific class actually helps the user.  Am I missing something?  There
> > really is no need for a user to know about factories, etc...
> >
> > -- Rob
> >
> >
> > On 2 August 2013 15:13, Rafael Schloming <rh...@alum.mit.edu> wrote:
> >
> >> On Fri, Aug 2, 2013 at 4:44 AM, Phil Harvey <phil@philharveyonline.com
> >> >wrote:
> >>
> >> > I agree that o.a.q.p.Proton is, overall, an improvement.  I was partly
> >> > responsible for creating the ProtonFactoryLoader and XXXFactory
> classes,
> >> > and acknowledge that they make life too hard for the user.
> >> >
> >> > This was a result of trying to meet the following design goals:
> >> > 1. User code should not need to have a compile-time dependency on any
> >> > proton-c/j/jni classes.  Given our current separation of the
> proton-api
> >> > from the proton-impl/proton-jni modules, it means user code should
> only
> >> > depend on proton-api at compile-time.
> >> > 2. Classes from the various "top level packages", such as engine,
> >> messenger
> >> > etc, should be kept separate unless they really need to be together.
> >> >
> >> > I still believe in goal 1 (though this will be discussed at greater
> >> length
> >> > on the related thread [1]), but am relaxed about item 2.
> >> >
> >>
> >> Thanks for describing the goals, it's helpful to have them written
> down. I
> >> personally don't feel that the Proton class is violating (2) in an
> >> important way so long as engine and messenger remain otherwise
> unentwined.
> >>
> >> I generally agree with (1) also, however I think it could use some
> further
> >> refinement. At the root of (1) is the desire to make it clear and
> obvious
> >> to developers if/when they are depending on the characteristics of a
> given
> >> implementation rather than on a more abstracted interface. Probably the
> >> most common example of this sort of thing within Java would be typical
> >> collections usage of interface/impl splits, e.g.:
> >>
> >>     List foo = new ArrayList();
> >>     ArrayList bar = new ArrayList();
> >>     LinkedList baz = new LinkedList();
> >>
> >> The suggested pattern for the Proton class would be following this
> pattern
> >> exactly:
> >>
> >>     Proton p = new ProtonJ();
> >>     ProtonJ pj = new ProtonJ();
> >>     ProtonC pc = new ProtonC();
> >>
> >> Now this pattern of course doesn't really speak to classpaths at all.
> The
> >> classpath issue is really entirely orthogonal to the interface/impl
> >> distinction. Right now we have separate classpaths, but a muddled
> >> interface/impl distinction since the impl jar adds new interfaces into
> >> packages belonging to the API jar, and the API jar has stuff in it that
> is
> >> really part of a specific impl. Likewise, you can have a clear
> >> interface/impl distinctions within a single jar as is the case with java
> >> collections.
> >>
> >> I'd argue that the classpath thing is really a distinct goal/requirement
> >> and is really more about a discovery mechanism for independent or third
> >> party implementations. I don't personally feel that this is a necessary
> >> requirement for us at this point, but I'm fairly relaxed if other people
> >> would like to support it.
> >>
> >> Given the above refinement of (1) into (1a) interface/impl split and
> (1b)
> >> independently implementable API, I would find it a bit odd to put the
> >> ProtonJ/ProtonC classes into the API package since that would introduce
> a
> >> dependency from the API package back to those impls (even if its only a
> >> runtime dependency) and would effectively give those impls an elevated
> >> position which in some sense is fine, but also seems contrary to the
> >> independently implementable notion in the first place. It seems like
> what
> >> you'd want in the API package is purely a generic discovery mechanism
> that
> >> would work for any implementation.
> >>
> >> As I said above, I don't feel like such a discovery mechanism is really
> a
> >> requirement for us right now. I think actually having a complicated
> >> discovery/factory pattern is in some ways detrimental as it creates a
> >> barrier to entry for all users when most don't care about the
> flexibility
> >> it offers (at least right now) and if they do care about that
> flexibility
> >> it is easy enough for them to build their own. In fact modulo exception
> >> handling it is really just one extra line of code:
> >>
> >>     Class impl = Class.forName(System.getProperty("blah"));
> >>     Proton p = (Proton) impl.newInstance();
> >>
> >> So I'd personally say go for the simple interface/impl split pattern
> that
> >> everyone knows and is used to and don't worry about a generic discovery
> >> mechanism until we actually have enough implementations for it to be
> >> warranted.
> >>
> >> --Rafael
> >>
>
>
>
> --
> Hiram Chirino
>
> Engineering | Red Hat, Inc.
>
> hchirino@redhat.com | fusesource.com | redhat.com
>
> skype: hiramchirino | twitter: @hiramchirino
>
> blog: Hiram Chirino's Bit Mojo
>

Re: proton-j API factory simplification.

Posted by Hiram Chirino <hi...@hiramchirino.com>.
You guys also need to keep in mind that doing dynamic loading of
implementations classes may need to be implemented differently based
on the container that the app is running in.  A good example is OSGi.
The way factories are currently implemented would probably not work
there.  So it's best to avoid getting into the factory business to
begin with.


On Fri, Aug 2, 2013 at 10:55 AM, Rob Godfrey <ro...@gmail.com> wrote:
> Given the Proton class doesn't require the user to know which
> implementation they are using (but allows them to explicitly ask for a
> particular implementation type if they so desire) I'm a little confused how
> adding the requirement for the user to instantiate an implementation
> specific class actually helps the user.  Am I missing something?  There
> really is no need for a user to know about factories, etc...
>
> -- Rob
>
>
> On 2 August 2013 15:13, Rafael Schloming <rh...@alum.mit.edu> wrote:
>
>> On Fri, Aug 2, 2013 at 4:44 AM, Phil Harvey <phil@philharveyonline.com
>> >wrote:
>>
>> > I agree that o.a.q.p.Proton is, overall, an improvement.  I was partly
>> > responsible for creating the ProtonFactoryLoader and XXXFactory classes,
>> > and acknowledge that they make life too hard for the user.
>> >
>> > This was a result of trying to meet the following design goals:
>> > 1. User code should not need to have a compile-time dependency on any
>> > proton-c/j/jni classes.  Given our current separation of the proton-api
>> > from the proton-impl/proton-jni modules, it means user code should only
>> > depend on proton-api at compile-time.
>> > 2. Classes from the various "top level packages", such as engine,
>> messenger
>> > etc, should be kept separate unless they really need to be together.
>> >
>> > I still believe in goal 1 (though this will be discussed at greater
>> length
>> > on the related thread [1]), but am relaxed about item 2.
>> >
>>
>> Thanks for describing the goals, it's helpful to have them written down. I
>> personally don't feel that the Proton class is violating (2) in an
>> important way so long as engine and messenger remain otherwise unentwined.
>>
>> I generally agree with (1) also, however I think it could use some further
>> refinement. At the root of (1) is the desire to make it clear and obvious
>> to developers if/when they are depending on the characteristics of a given
>> implementation rather than on a more abstracted interface. Probably the
>> most common example of this sort of thing within Java would be typical
>> collections usage of interface/impl splits, e.g.:
>>
>>     List foo = new ArrayList();
>>     ArrayList bar = new ArrayList();
>>     LinkedList baz = new LinkedList();
>>
>> The suggested pattern for the Proton class would be following this pattern
>> exactly:
>>
>>     Proton p = new ProtonJ();
>>     ProtonJ pj = new ProtonJ();
>>     ProtonC pc = new ProtonC();
>>
>> Now this pattern of course doesn't really speak to classpaths at all. The
>> classpath issue is really entirely orthogonal to the interface/impl
>> distinction. Right now we have separate classpaths, but a muddled
>> interface/impl distinction since the impl jar adds new interfaces into
>> packages belonging to the API jar, and the API jar has stuff in it that is
>> really part of a specific impl. Likewise, you can have a clear
>> interface/impl distinctions within a single jar as is the case with java
>> collections.
>>
>> I'd argue that the classpath thing is really a distinct goal/requirement
>> and is really more about a discovery mechanism for independent or third
>> party implementations. I don't personally feel that this is a necessary
>> requirement for us at this point, but I'm fairly relaxed if other people
>> would like to support it.
>>
>> Given the above refinement of (1) into (1a) interface/impl split and (1b)
>> independently implementable API, I would find it a bit odd to put the
>> ProtonJ/ProtonC classes into the API package since that would introduce a
>> dependency from the API package back to those impls (even if its only a
>> runtime dependency) and would effectively give those impls an elevated
>> position which in some sense is fine, but also seems contrary to the
>> independently implementable notion in the first place. It seems like what
>> you'd want in the API package is purely a generic discovery mechanism that
>> would work for any implementation.
>>
>> As I said above, I don't feel like such a discovery mechanism is really a
>> requirement for us right now. I think actually having a complicated
>> discovery/factory pattern is in some ways detrimental as it creates a
>> barrier to entry for all users when most don't care about the flexibility
>> it offers (at least right now) and if they do care about that flexibility
>> it is easy enough for them to build their own. In fact modulo exception
>> handling it is really just one extra line of code:
>>
>>     Class impl = Class.forName(System.getProperty("blah"));
>>     Proton p = (Proton) impl.newInstance();
>>
>> So I'd personally say go for the simple interface/impl split pattern that
>> everyone knows and is used to and don't worry about a generic discovery
>> mechanism until we actually have enough implementations for it to be
>> warranted.
>>
>> --Rafael
>>



-- 
Hiram Chirino

Engineering | Red Hat, Inc.

hchirino@redhat.com | fusesource.com | redhat.com

skype: hiramchirino | twitter: @hiramchirino

blog: Hiram Chirino's Bit Mojo

Re: proton-j API factory simplification.

Posted by Rob Godfrey <ro...@gmail.com>.
Given the Proton class doesn't require the user to know which
implementation they are using (but allows them to explicitly ask for a
particular implementation type if they so desire) I'm a little confused how
adding the requirement for the user to instantiate an implementation
specific class actually helps the user.  Am I missing something?  There
really is no need for a user to know about factories, etc...

-- Rob


On 2 August 2013 15:13, Rafael Schloming <rh...@alum.mit.edu> wrote:

> On Fri, Aug 2, 2013 at 4:44 AM, Phil Harvey <phil@philharveyonline.com
> >wrote:
>
> > I agree that o.a.q.p.Proton is, overall, an improvement.  I was partly
> > responsible for creating the ProtonFactoryLoader and XXXFactory classes,
> > and acknowledge that they make life too hard for the user.
> >
> > This was a result of trying to meet the following design goals:
> > 1. User code should not need to have a compile-time dependency on any
> > proton-c/j/jni classes.  Given our current separation of the proton-api
> > from the proton-impl/proton-jni modules, it means user code should only
> > depend on proton-api at compile-time.
> > 2. Classes from the various "top level packages", such as engine,
> messenger
> > etc, should be kept separate unless they really need to be together.
> >
> > I still believe in goal 1 (though this will be discussed at greater
> length
> > on the related thread [1]), but am relaxed about item 2.
> >
>
> Thanks for describing the goals, it's helpful to have them written down. I
> personally don't feel that the Proton class is violating (2) in an
> important way so long as engine and messenger remain otherwise unentwined.
>
> I generally agree with (1) also, however I think it could use some further
> refinement. At the root of (1) is the desire to make it clear and obvious
> to developers if/when they are depending on the characteristics of a given
> implementation rather than on a more abstracted interface. Probably the
> most common example of this sort of thing within Java would be typical
> collections usage of interface/impl splits, e.g.:
>
>     List foo = new ArrayList();
>     ArrayList bar = new ArrayList();
>     LinkedList baz = new LinkedList();
>
> The suggested pattern for the Proton class would be following this pattern
> exactly:
>
>     Proton p = new ProtonJ();
>     ProtonJ pj = new ProtonJ();
>     ProtonC pc = new ProtonC();
>
> Now this pattern of course doesn't really speak to classpaths at all. The
> classpath issue is really entirely orthogonal to the interface/impl
> distinction. Right now we have separate classpaths, but a muddled
> interface/impl distinction since the impl jar adds new interfaces into
> packages belonging to the API jar, and the API jar has stuff in it that is
> really part of a specific impl. Likewise, you can have a clear
> interface/impl distinctions within a single jar as is the case with java
> collections.
>
> I'd argue that the classpath thing is really a distinct goal/requirement
> and is really more about a discovery mechanism for independent or third
> party implementations. I don't personally feel that this is a necessary
> requirement for us at this point, but I'm fairly relaxed if other people
> would like to support it.
>
> Given the above refinement of (1) into (1a) interface/impl split and (1b)
> independently implementable API, I would find it a bit odd to put the
> ProtonJ/ProtonC classes into the API package since that would introduce a
> dependency from the API package back to those impls (even if its only a
> runtime dependency) and would effectively give those impls an elevated
> position which in some sense is fine, but also seems contrary to the
> independently implementable notion in the first place. It seems like what
> you'd want in the API package is purely a generic discovery mechanism that
> would work for any implementation.
>
> As I said above, I don't feel like such a discovery mechanism is really a
> requirement for us right now. I think actually having a complicated
> discovery/factory pattern is in some ways detrimental as it creates a
> barrier to entry for all users when most don't care about the flexibility
> it offers (at least right now) and if they do care about that flexibility
> it is easy enough for them to build their own. In fact modulo exception
> handling it is really just one extra line of code:
>
>     Class impl = Class.forName(System.getProperty("blah"));
>     Proton p = (Proton) impl.newInstance();
>
> So I'd personally say go for the simple interface/impl split pattern that
> everyone knows and is used to and don't worry about a generic discovery
> mechanism until we actually have enough implementations for it to be
> warranted.
>
> --Rafael
>

Re: proton-j API factory simplification.

Posted by Rafael Schloming <rh...@alum.mit.edu>.
On Fri, Aug 2, 2013 at 4:44 AM, Phil Harvey <ph...@philharveyonline.com>wrote:

> I agree that o.a.q.p.Proton is, overall, an improvement.  I was partly
> responsible for creating the ProtonFactoryLoader and XXXFactory classes,
> and acknowledge that they make life too hard for the user.
>
> This was a result of trying to meet the following design goals:
> 1. User code should not need to have a compile-time dependency on any
> proton-c/j/jni classes.  Given our current separation of the proton-api
> from the proton-impl/proton-jni modules, it means user code should only
> depend on proton-api at compile-time.
> 2. Classes from the various "top level packages", such as engine, messenger
> etc, should be kept separate unless they really need to be together.
>
> I still believe in goal 1 (though this will be discussed at greater length
> on the related thread [1]), but am relaxed about item 2.
>

Thanks for describing the goals, it's helpful to have them written down. I
personally don't feel that the Proton class is violating (2) in an
important way so long as engine and messenger remain otherwise unentwined.

I generally agree with (1) also, however I think it could use some further
refinement. At the root of (1) is the desire to make it clear and obvious
to developers if/when they are depending on the characteristics of a given
implementation rather than on a more abstracted interface. Probably the
most common example of this sort of thing within Java would be typical
collections usage of interface/impl splits, e.g.:

    List foo = new ArrayList();
    ArrayList bar = new ArrayList();
    LinkedList baz = new LinkedList();

The suggested pattern for the Proton class would be following this pattern
exactly:

    Proton p = new ProtonJ();
    ProtonJ pj = new ProtonJ();
    ProtonC pc = new ProtonC();

Now this pattern of course doesn't really speak to classpaths at all. The
classpath issue is really entirely orthogonal to the interface/impl
distinction. Right now we have separate classpaths, but a muddled
interface/impl distinction since the impl jar adds new interfaces into
packages belonging to the API jar, and the API jar has stuff in it that is
really part of a specific impl. Likewise, you can have a clear
interface/impl distinctions within a single jar as is the case with java
collections.

I'd argue that the classpath thing is really a distinct goal/requirement
and is really more about a discovery mechanism for independent or third
party implementations. I don't personally feel that this is a necessary
requirement for us at this point, but I'm fairly relaxed if other people
would like to support it.

Given the above refinement of (1) into (1a) interface/impl split and (1b)
independently implementable API, I would find it a bit odd to put the
ProtonJ/ProtonC classes into the API package since that would introduce a
dependency from the API package back to those impls (even if its only a
runtime dependency) and would effectively give those impls an elevated
position which in some sense is fine, but also seems contrary to the
independently implementable notion in the first place. It seems like what
you'd want in the API package is purely a generic discovery mechanism that
would work for any implementation.

As I said above, I don't feel like such a discovery mechanism is really a
requirement for us right now. I think actually having a complicated
discovery/factory pattern is in some ways detrimental as it creates a
barrier to entry for all users when most don't care about the flexibility
it offers (at least right now) and if they do care about that flexibility
it is easy enough for them to build their own. In fact modulo exception
handling it is really just one extra line of code:

    Class impl = Class.forName(System.getProperty("blah"));
    Proton p = (Proton) impl.newInstance();

So I'd personally say go for the simple interface/impl split pattern that
everyone knows and is used to and don't worry about a generic discovery
mechanism until we actually have enough implementations for it to be
warranted.

--Rafael

Re: proton-j API factory simplification.

Posted by Phil Harvey <ph...@philharveyonline.com>.
Corrected typo in the code inline:


On 2 August 2013 09:44, Phil Harvey <ph...@philharveyonline.com> wrote:

> I agree that o.a.q.p.Proton is, overall, an improvement.  I was partly
> responsible for creating the ProtonFactoryLoader and XXXFactory classes,
> and acknowledge that they make life too hard for the user.
>
> This was a result of trying to meet the following design goals:
> 1. User code should not need to have a compile-time dependency on any
> proton-c/j/jni classes.  Given our current separation of the proton-api
> from the proton-impl/proton-jni modules, it means user code should only
> depend on proton-api at compile-time.
> 2. Classes from the various "top level packages", such as engine,
> messenger etc, should be kept separate unless they really need to be
> together.
>
> I still believe in goal 1 (though this will be discussed at greater length
> on the related thread [1]), but am relaxed about item 2.
>
> So, I'd be in favour of Hiram's proposal if ProtonJ and ProtonC reside in
> proton-api.jar.  This would be very easy to do, e.g.
>
> public class ProtonJ extends Proton
> {
>   ...
>
>   public ProtonJ()
>   {
>     engineFactory = new
> ProtonFactoryLoader<EngineFactory>(EngineFactory.class, PROTON_J);
>
        // oops, should have been:
        engineFactory = new
ProtonFactoryLoader<EngineFactory>(EngineFactory.class,
PROTON_J).loadFactory();

>     ...
>   }
>   ...
> }
>
>
> Phil
>
>
> [1]
> http://qpid.2158936.n2.nabble.com/Java-Packaging-Organizational-Issues-tt7596353.html
>
>
> On 1 August 2013 18:18, Rafael Schloming <rh...@alum.mit.edu> wrote:
>
>> I like this idea. Right now I'm at a loss to understand what all the
>> factory business is for, and I'm actually pretty familiar with the
>> codebase. I don't think our users stand a snowballs chance in hell of
>> sorting through the myriad of factories, factory impls, service loaders,
>> and service loader impls needed in order to get started with even a simple
>> example.
>>
>> The current Proton.java class is a step in the right direction, however
>> with all the other factories lying around it kind of gets lost in the
>> noise. It would be good if we could enforce a single entry point at the
>> code level, and what you're describing sounds like it would be pretty
>> simple/easy to explain to users. It would be nice if we could get to the
>> point where we have only one public entry point class inside each impl.
>> IMHO, that would make the API way more discoverable even with only minimal
>> javadoc.
>>
>> --Rafael
>>
>>
>>
>> On Thu, Aug 1, 2013 at 12:50 PM, Hiram Chirino <hiram@hiramchirino.com
>> >wrote:
>>
>> > Hi folks,
>> >
>> > I was just thinking perhaps we should simplify all the factory stuff
>> > in the proton API.  Mostly get rid of it.  Don't think it's really
>> > needed.  Mainly I think we need to make Proton an interface and let
>> > folks assign it the desired implementation.  Something like:
>> >
>> > Proton p = new ProtonJ();
>> >
>> > or
>> >
>> > Proton p = new ProtonC();
>> >
>> > where ProtonJ and ProtonC are in the respective implementation jars.
>> >
>> > if folks really want to make it configurable, they can easily build an
>> > if statement to pick the impl that they desire.
>> >
>> >
>> > --
>> > Hiram Chirino
>> >
>> > Engineering | Red Hat, Inc.
>> >
>> > hchirino@redhat.com | fusesource.com | redhat.com
>> >
>> > skype: hiramchirino | twitter: @hiramchirino
>> >
>> > blog: Hiram Chirino's Bit Mojo
>> >
>>
>
>

Re: proton-j API factory simplification.

Posted by Phil Harvey <ph...@philharveyonline.com>.
I agree that o.a.q.p.Proton is, overall, an improvement.  I was partly
responsible for creating the ProtonFactoryLoader and XXXFactory classes,
and acknowledge that they make life too hard for the user.

This was a result of trying to meet the following design goals:
1. User code should not need to have a compile-time dependency on any
proton-c/j/jni classes.  Given our current separation of the proton-api
from the proton-impl/proton-jni modules, it means user code should only
depend on proton-api at compile-time.
2. Classes from the various "top level packages", such as engine, messenger
etc, should be kept separate unless they really need to be together.

I still believe in goal 1 (though this will be discussed at greater length
on the related thread [1]), but am relaxed about item 2.

So, I'd be in favour of Hiram's proposal if ProtonJ and ProtonC reside in
proton-api.jar.  This would be very easy to do, e.g.

public class ProtonJ extends Proton
{
  ...

  public ProtonJ()
  {
    engineFactory = new
ProtonFactoryLoader<EngineFactory>(EngineFactory.class, PROTON_J);
    ...
  }
  ...
}


Phil


[1]
http://qpid.2158936.n2.nabble.com/Java-Packaging-Organizational-Issues-tt7596353.html


On 1 August 2013 18:18, Rafael Schloming <rh...@alum.mit.edu> wrote:

> I like this idea. Right now I'm at a loss to understand what all the
> factory business is for, and I'm actually pretty familiar with the
> codebase. I don't think our users stand a snowballs chance in hell of
> sorting through the myriad of factories, factory impls, service loaders,
> and service loader impls needed in order to get started with even a simple
> example.
>
> The current Proton.java class is a step in the right direction, however
> with all the other factories lying around it kind of gets lost in the
> noise. It would be good if we could enforce a single entry point at the
> code level, and what you're describing sounds like it would be pretty
> simple/easy to explain to users. It would be nice if we could get to the
> point where we have only one public entry point class inside each impl.
> IMHO, that would make the API way more discoverable even with only minimal
> javadoc.
>
> --Rafael
>
>
>
> On Thu, Aug 1, 2013 at 12:50 PM, Hiram Chirino <hiram@hiramchirino.com
> >wrote:
>
> > Hi folks,
> >
> > I was just thinking perhaps we should simplify all the factory stuff
> > in the proton API.  Mostly get rid of it.  Don't think it's really
> > needed.  Mainly I think we need to make Proton an interface and let
> > folks assign it the desired implementation.  Something like:
> >
> > Proton p = new ProtonJ();
> >
> > or
> >
> > Proton p = new ProtonC();
> >
> > where ProtonJ and ProtonC are in the respective implementation jars.
> >
> > if folks really want to make it configurable, they can easily build an
> > if statement to pick the impl that they desire.
> >
> >
> > --
> > Hiram Chirino
> >
> > Engineering | Red Hat, Inc.
> >
> > hchirino@redhat.com | fusesource.com | redhat.com
> >
> > skype: hiramchirino | twitter: @hiramchirino
> >
> > blog: Hiram Chirino's Bit Mojo
> >
>

Re: proton-j API factory simplification.

Posted by Rafael Schloming <rh...@alum.mit.edu>.
I like this idea. Right now I'm at a loss to understand what all the
factory business is for, and I'm actually pretty familiar with the
codebase. I don't think our users stand a snowballs chance in hell of
sorting through the myriad of factories, factory impls, service loaders,
and service loader impls needed in order to get started with even a simple
example.

The current Proton.java class is a step in the right direction, however
with all the other factories lying around it kind of gets lost in the
noise. It would be good if we could enforce a single entry point at the
code level, and what you're describing sounds like it would be pretty
simple/easy to explain to users. It would be nice if we could get to the
point where we have only one public entry point class inside each impl.
IMHO, that would make the API way more discoverable even with only minimal
javadoc.

--Rafael



On Thu, Aug 1, 2013 at 12:50 PM, Hiram Chirino <hi...@hiramchirino.com>wrote:

> Hi folks,
>
> I was just thinking perhaps we should simplify all the factory stuff
> in the proton API.  Mostly get rid of it.  Don't think it's really
> needed.  Mainly I think we need to make Proton an interface and let
> folks assign it the desired implementation.  Something like:
>
> Proton p = new ProtonJ();
>
> or
>
> Proton p = new ProtonC();
>
> where ProtonJ and ProtonC are in the respective implementation jars.
>
> if folks really want to make it configurable, they can easily build an
> if statement to pick the impl that they desire.
>
>
> --
> Hiram Chirino
>
> Engineering | Red Hat, Inc.
>
> hchirino@redhat.com | fusesource.com | redhat.com
>
> skype: hiramchirino | twitter: @hiramchirino
>
> blog: Hiram Chirino's Bit Mojo
>