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

Reply via email to