Thanks Tim and BJ, (In hindsight I should have mentioned that the example I had in mind for changing hashCode was something like a bugfix (ie compatible change), sorry about that.) So yes, my point is both about how to handle non-API-breaking changes of an API artefact and whether class implementations with method bodies actually belong in a true OSGi API. Thanks for answering both of these! My typical scenario will be a micro version change (bugfix, JavaDoc change, etc) and for our "single API" bundles this means I can keep going with the same micro update to both package version and Maven artefact version. Both would be 1.0.1 in the example. The DTO spec looks interesting but we will probably not use it as we try to declare our APIs without runtime platform dependencies such as the org.osgi.dto.DTO superclass. Also, even though I myself appreciate method-less objects with public members, we have "forces" pushing for getters and setters. Partly this is because some want the ability to use the classes together with dynamic proxies (I don't remember a smashing use-case) and then methods as entry points are needed.
Best regards Mike Timothy Ward wrote: Hi Mike, The change you need to make depends on the contract for your hashCode() method. Whatever you change you really should change your version. API should really only use the same version if it's bit identical. I would normally not bother to change the version when just using a different compiler, but even that is technically a change. If you have made the mistake of specifying the hashing function (they nearly did this with String in Java) then: * Changing the implementation in a way which changes the returned value is a breaking change, and would be a MAJOR version bump * Changing the implementation in a way which doesn't change the returned value breaks no-one, and would be a MICRO change If you have stuck with the standard hash code contract, which means that the algorithm isn't part of your API, then: * Changing the implementation in a way which changes the returned value is *not* a breaking change as nobody should rely on it. This makes it a MICRO change. * Changing the implementation in a way which doesn't change the returned value still breaks no-one, and would be a MICRO change As for your other questions, it's hard to talk specifics without more detail, but. * In general if value objects are part of your API then you should expose them directly as API. * Factories are often superfluous in this situation, but it does depend on context. * Value objects in general are a "Good Thing", and if you make sure they really are value objects (final, immutable, serialisable in some way, and with no behaviours) then they make Remote Services work really easily and well. Regards, Tim On 29 Sep 2014, at 10:27, Mike Wilson <[email protected]> wrote: What's your best practice when changing value object classes? Consider: myservice-api-1.0.0.jar META-INF/MANIFEST.MF Export-Package: myservice;version="1.0" public interface MyService { void doStuffWithValue(MyValue v) ... MyValue returnValue() ... } public class MyValue { String member1; int member2; public boolean equals(Object obj) ... public int hashCode() ... } myservice-impl-1.0.0.jar class MyServiceImpl implements MyService { ... } Now if I need to update the implementation of MyValue's hashCode method, what would you do? - not update API version - update API version - wrong design, use a factory pattern for MyValue - wrong question, you should avoid value objects altogether - <other suggestions> Thanks Mike Wilson _______________________________________________ OSGi Developer Mail List [email protected] https://mail.osgi.org/mailman/listinfo/osgi-dev BJ Hargrave wrote: > From: Mike Wilson <[email protected]> > What's your best practice when changing value object classes? > > Consider: > > myservice-api-1.0.0.jar > META-INF/MANIFEST.MF > Export-Package: myservice;version="1.0" > public interface MyService { > void doStuffWithValue(MyValue v) ... > MyValue returnValue() ... > } > public class MyValue { > String member1; > int member2; > public boolean equals(Object obj) ... > public int hashCode() ... > } > > myservice-impl-1.0.0.jar > class MyServiceImpl implements MyService { > ... > } > > Now if I need to update the implementation of MyValue's > hashCode method, what would you do? If you are using the specification of hashCode from Object, then the specific hash value is an implementation detail. Update away and probably bump the micro version of the package/bundle. If however MyValue specifically defines how to compute the hash value from the values and you want to change that, then you make have a breaking change in your API since you have allowed people to depend upon the specific values. > - not update API version > - update API version > - wrong design, use a factory pattern for MyValue > - wrong question, you should avoid value objects altogether Value objects are fine but you should probably not specify any behavior on them because they are then more just values. See DTOs in the OSGi spec. For DTOs, we use equals and hashCode from Object. That means, object identity. > - <other suggestions> -- BJ Hargrave Senior Technical Staff Member, IBM OSGi Fellow and CTO of the <http://www.osgi.org/> OSGi Alliance <mailto:[email protected]> [email protected] office: +1 386 848 1781 mobile: +1 386 848 3788
_______________________________________________ OSGi Developer Mail List [email protected] https://mail.osgi.org/mailman/listinfo/osgi-dev
