That’s the current state. Changing (e.g. by enforcing a builder pattern or something) would add unneeded complexity for the user if you ask me.
In fact, the fact that the Entry fields are non-final is the way Jini knows it’s a field and not a constant. i.e. in the AbstractEntry docs, it specifically says "The entry fields of an Entry are its public, non-primitive, non-static, non-transient, non-final fields." Where do we use entries? Typically in doing Service registrations and lookups. Most users can understand that the Entry is going to be serialized and used remotely. Add to documentation? Sure. Change the API? Maybe add an optional builder-style object. (e.g. create a StatusBuilder that acts as a bean and generates Status entries). But even so, it seems like a small enough part of using Jini to not bother much with. Another way to think about it is that Entries don’t mean much until you send them somewhere. So you need to make sure they’re all setup and everything they refer to is stable when you send them. To me, that’s a user-understanding item that’s difficult to enforce through code. Cheers, Greg Trasuk. > On Sep 8, 2015, at 7:16 AM, Bryan Thompson <br...@systap.com> wrote: > > Document as effectively immutable by contract. User error if relies on > publication of modified array contents? > On Sep 8, 2015 6:48 AM, "Peter" <j...@zeus.net.au> wrote: > >> Brian, >> >> That was my first reaction too, so I read up on why Entries were designed >> as they are, Entries are a collection of objects, they're not supposed to >> be objects themselves. They are used for searching / comparing serial form. >> >> I basically came to the conclusion that an Entry's is most important in >> serial form, where it's immutable. An Entry's serial form is public, in >> other words it appears better to make all public fields final, than to >> encapsulate, the objects the final fields refer to must also be immutable >> and most are. >> >> However Entries containing arrays, present a problem, in that a reference >> to an array can be final, but its elements remain mutable, so arrays would >> need to be encapsulated, by a List. >> >> Entries are of course value objects, so it would seem appropriate they >> also be immutable. >> >> One complication is Beans, but since Beans have methods, instead of >> mutating the Entry, they can update their own reference to a new Entry >> object. >> >> Other classes with public fields: >> >> ServiceItem >> ServiceMatches >> ServiceTemplate >> >> These may be candiates for encapsulation or final fields. >> >> Regards, >> >> Peter. >> >> On 8/09/2015 7:52 PM, Bryan Thompson wrote: >> >>> Peter, >>> >>> Can you enumerate the cases here? Certainly there are the public fields >>> for entries. I would be in favor of encapsulating that at some point. >>> >>> Bryan >>> >>> On Tuesday, September 8, 2015, Peter<j...@zeus.net.au> wrote: >>> >>> It's also worth mentioning, while I was fixing a synchronization or >>>> concurrency bugs, I found it very hard to reason about the state of >>>> public >>>> mutable fields in a number of api objects, I'd do a lot of defensive >>>> copying and making sure I've published them safely, however it is >>>> difficult >>>> to ensure these objects don't escape from locked or safely published >>>> scope. >>>> >>>> While I understand that people have an expectation to be able to modify >>>> these fields, it would be much simpler if these object were immutable and >>>> people simply made a new copy instead of mutating them. A number of api >>>> classes also contain publicly accessible mutable arrays. >>>> >>>> It's possible to retain the serial form of these classes, while replacing >>>> arrays with immutable lists. >>>> >>>> This would improve performance and reduce memory consumption. >>>> >>>> I understand that to do so however, there would be a certain level of >>>> pain >>>> for developers. >>>> >>>> Regards, >>>> >>>> Peter. >>>> >>>> On 6/09/2015 9:41 PM, Peter wrote: >>>> >>>> On 5/09/2015 1:49 AM, Greg Trasuk wrote: >>>>> >>>>> On Sep 4, 2015, at 5:26 AM, Dawid Loubser<da...@travellinck.com> >>>>>> wrote: >>>>>> >>>>>>> And given the vision, experience and efforts of people like Peter, it >>>>>>> would almost be criminal to not break free from an old standard, to >>>>>>> miss >>>>>>> the potential of what may be. >>>>>>> >>>>>>> Speaking of which, I’ve always wondered, Peter, if you could tell us a >>>>>>> >>>>>> little about the Jini systems you’ve built and worked with in the >>>>>> past, and >>>>>> some of the issues you’ve seen in production? It would be great if we >>>>>> on >>>>>> the list could share some experiences - that would highlight areas >>>>>> where >>>>>> the standards get in the way, and we could change them. We are the >>>>>> standards body for Jini, after all. >>>>>> >>>>>> >>>>>> I can't say I've run data centres filled with Jini systems. I haven't >>>>> experienced difficulties writing or deploying services, although I >>>>> don't do >>>>> this on a large scale, however I've had trouble with security policy >>>>> files >>>>> and proxy trust. I don't like using URL's for policy files, so I >>>>> created a >>>>> policy service. I've included the service api for the policy service in >>>>> org.apache.river.api.security.RemotePolicy >>>>> >>>>> Basically when a node starts, it registers a RemotePolicy service with >>>>> the lookup service, an automated admin client receives an event, >>>>> contacts >>>>> the service and populates it with its security policy. >>>>> >>>>> The RemotePolicy service requires the policy provider to implement >>>>> org.apache.river.api.security.RevocablePolicy. In this case the >>>>> implementation of the RemotePolicy service hasn't been contributed, >>>>> however >>>>> it is pretty obvious how it works. >>>>> >>>>> The abstract class, org.apache.river.api.security.PermissionGrant, is an >>>>> object version of the grant statement in a policy file. The >>>>> implementations of this class are package private as is the serial form >>>>> of >>>>> these classes. >>>>> >>>>> Unlike PermissionCollection, PermissionGrant's are immutable, they're >>>>> used in all River policy implementations. The class allow >>>>> PermissionCollection's to be created on demand, with all the latest >>>>> dynamic >>>>> and static grants, ordered optimally to eliminate unnecessary permission >>>>> checks. >>>>> >>>>> Since policy implementations are nested, another interface, >>>>> org.apache.river.api.security.ScalableNestedPolicy allows the top level >>>>> policy to collect all PermissionGrant's from underlying policies, before >>>>> creating an optimally ordered PermissionCollection for policy permission >>>>> implies checks. >>>>> >>>>> These interfaces and classes make it much easier to manage security >>>>> policies, belonging to to an administrator in a shared djinn. Each >>>>> administrator can idenfity their services, using an Entry, then filter >>>>> appropriately. The RemotePolicy service only uses a bootstrap proxy, no >>>>> codebase is downloaded. It is recommended to use secure endpoints. >>>>> Calls >>>>> executed on the RemotePolicy service are run with the administrator's >>>>> subject. >>>>> >>>>> For services that are Activatable, or require a thread after >>>>> construction >>>>> is completed, an interface org.apache.river.api.util.Startable, is >>>>> provided, if a service implements this interface, Phoenix, or the start >>>>> package will call it after constructing the service. Jini was never >>>>> updated to Java 5, in this version of Java, the JMM was updated, I >>>>> think if >>>>> the original Jini team had done so, they would have done something like >>>>> this. It's the simplest and safest way of exporting a service after >>>>> construction, although the Startable interface doesn't just provide for >>>>> safe exporting, it can be used to start threads or utilities the service >>>>> uses after construction as well. >>>>> >>>>> When an object is instantiated, the jmm guarantees a memory fence will >>>>> occur that ensures that all threads will see the fully constructed >>>>> object. >>>>> When an object allows a reference to itself to escape during >>>>> construction, >>>>> there is no guarantees that other threads will see the fully constructed >>>>> object. For synchronized access to fields, all accesses must be >>>>> synchronized, so even if another thread uses synchronization, if the >>>>> object >>>>> wasn't safely published there's no guarantee that a thread will see the >>>>> fully constructed object. >>>>> >>>>> I've found the best place to discuss the JMM is the concurrency interest >>>>> mail list. >>>>> >>>>> The final thing I wish to discuss, is the new classes ing >>>>> org.apache.river.api.net.* RFC3896URLClassLoader and Uri. >>>>> >>>>> Uri is a RFC3986 compliant Uri, it isn't Serializable and since it is >>>>> based on the RFC3986 standard it is also not going to change. This >>>>> class >>>>> is relevant throughout River, from normalization of codebase >>>>> annotations to >>>>> replication of Codebase.implies functionality. Uri, unlike java.net.URI >>>>> (RFC2396 based) it is fully compliant with the standard and doesn't >>>>> extend >>>>> it, this is very important from a performance perspective, as bitshift >>>>> operations can be utilised during normalization. >>>>> >>>>> RFC3986URLClassLoader, uses URL's that are parsed to be compliant with >>>>> RFC3986, this is to avoid DNS calls in java.security.SecureClassLoader, >>>>> this is both for performance and security reasons. >>>>> >>>>> I'd like to see these classes added to the public api, anyone that uses >>>>> URLClassLoader with network URL's should use RFC3986URLClassLoader >>>>> instead. Uri will have even more relevance for Java 9, since modular >>>>> codebase annotations in Java 9 will be RFC3986 compliant. Talking to >>>>> the >>>>> devs on OpenJDK, they've tried making java.net.URI RFC3986 compliant, >>>>> but >>>>> it causes test failures for them, also because java.net.URI extends the >>>>> previous standard, their RFC3986 version will probably also need to, so >>>>> they'll miss out on some serious performance benefits provided by >>>>> bitshift >>>>> operations. >>>>> >>>>> As for the future, once I have security sorted, I plan to make publicly >>>>> available, a lookup service on IPv6, using the discovery announcement >>>>> protocol over IPv6 multicast. Here people will be able to register >>>>> their >>>>> own services and others will be able to use them. The advantage that >>>>> River >>>>> has over web services is it's distributed, unlike its web service >>>>> cousins >>>>> that are client-server based. For instance, the cloud is client server >>>>> based, with resources in a data centre. In the distributed model, >>>>> nodes >>>>> can both consume services and provide them. >>>>> >>>>> As for problems with the standards, I'd suggest the proxy trust model is >>>>> overly complex, I'd like to revise it. >>>>> >>>>> Otherwise there is a lot to like and a lot of well thought out designs, >>>>> but there are some parts that time has not been so kind to, that need >>>>> repairing by modern standards. >>>>> >>>>> Regards, >>>>> >>>>> Peter. >>>>> >>>>> For myself, the big issue was always ease of writing and deploying >>>>> >>>>>> services, which is why I wrote the Harvester application container >>>>>> back in >>>>>> the day, and the River Container (which I really must get around to >>>>>> thinking up a new name for) more recently. When you get more than a >>>>>> few >>>>>> machines involved, things get complicated to manage, although I haven’t >>>>>> done a system big enough to show the kind of QOS issues that Dennis’ >>>>>> Rio >>>>>> project was designed to address. >>>>>> >>>>>> Cheers, >>>>>> >>>>>> Greg Trasuk >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>