tag:blogger.com,1999:blog-8656465666508353224.comments2023-05-26T04:21:31.288-07:00Mutability Detector BlogGraham Allanhttp://www.blogger.com/profile/16539618370362116733noreply@blogger.comBlogger32125tag:blogger.com,1999:blog-8656465666508353224.post-66019983515005386062021-04-01T19:36:32.977-07:002021-04-01T19:36:32.977-07:00I'm really very sorry it's taken me so lon...I'm really very sorry it's taken me so long to respond to your question. See the section on getting started, particularly: "Post to the mailing list and announce your interest in contributing, tell me a little about yourself. Read this blog, and try to use Mutability Detector".<br /><br />WeWarahttps://www.blogger.com/profile/02688012354054151235noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-68273975559959019042021-04-01T19:32:34.464-07:002021-04-01T19:32:34.464-07:00EnterEnterWarahttps://www.blogger.com/profile/02688012354054151235noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-15267175682034222122015-11-22T07:44:41.222-08:002015-11-22T07:44:41.222-08:00Hi, apologies for long response time. I'm sure...Hi, apologies for long response time. I'm sure I replied to this, but I suspect blogspot swallowed the response.<br /><br />This is now an open issue and will hopefully be resolved soon: https://github.com/MutabilityDetector/MutabilityDetector/issues/64Graham Allanhttps://www.blogger.com/profile/16539618370362116733noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-79108499169811731312015-08-11T03:34:30.710-07:002015-08-11T03:34:30.710-07:00Hi Graham,
thanks for you reply! Now I understand...Hi Graham,<br /><br />thanks for you reply! Now I understand the behaviour, though I think it's more desirable to make it consistent by design. I find it a bit confusing that String members are considered immutable, but the String class itself not. *At least* you should point that out in the documentation.<br /><br />Here's the background; I'm sure you'll find this is a perfect valid use case: I have an Event class that contains a couple of members which must be immutable and members that are not immutable. The must-be-immutable members have an annotation @EventVariable. So I wrote a Unit-Test that determines all @EventVariable members and requires these to be immutable. That works fine, until I saw that String members are not immutable. Then my research brought me to this page where I read String is considered immutable being a contradition to my unit tests.<br /><br />Best regards,<br />steffenAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-69082898293106193842015-08-04T13:02:54.229-07:002015-08-04T13:02:54.229-07:00That's an interesting point, I hadn't cons...That's an interesting point, I hadn't considered that before.<br /><br />I certainly could let the areEffectivelyImmutable() matcher accept classes that are immutable, but I'm not sure what the use case would be. Is this behaviour, albeit slightly confusing, preventing you from doing something?Grahamnoreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-76995927233006494972015-08-04T12:59:52.537-07:002015-08-04T12:59:52.537-07:00Hi Steffen,
Great to hear you're trying out t...Hi Steffen,<br /><br />Great to hear you're trying out the tool!<br /><br />With java.lang.String, you're not doing it wrong. The behaviour you see is by design. String is hardcoded to be immutable because the analysis is not powerful enough to detect its internal mutation is safe. This lead to lots of false positives of other classes, because the mutability is transitive, and kind of "infects" other classes. Hardcoding it allows classes that have String fields to still be considered immutable, but if you test the class directly, it gives the "real" result. I expected this behaviour would suit most users, as they don't make changes directly to String, instead, they use String in their own classes.<br /><br />Does that make sense?<br /><br />~ Graham (though posting anonymous as Google won't let me log in for some reason)Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-28396827831906754942015-08-03T11:10:11.414-07:002015-08-03T11:10:11.414-07:00Hi again,
same with "assertInstancesOf(myCla...Hi again,<br /><br />same with "assertInstancesOf(myClass, Matchers.anyOf(MutabilityMatchers.areImmutable(), MutabilityMatchers.areEffectivelyImmutable()));". And I get messages like "Expected: java.time.Instant to be EFFECTIVELY_IMMUTABLE, but: java.time.Instant is actually IMMUTABLE". Doesn't being immutable imply being effectively immutable?<br /><br /><br />Regards<br />SteffenAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-91813494718996443752015-08-03T10:45:40.983-07:002015-08-03T10:45:40.983-07:00Hi Graham,
thank you very much for your amazing t...Hi Graham,<br /><br />thank you very much for your amazing tool. But my first tests failed because I still get the message "Expected: java.lang.String to be IMMUTABLE, but: java.lang.String is actually NOT_IMMUTABLE". Well I added a maven dependency to "org.mutabilitydetector / MutabilityDetector / 0.9.5" and run "MutabilityAssert.assertImmutable(myClass)".<br /><br />What am I doing wrong?<br /><br />Regards,<br />SteffenAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-64270554694281568952013-12-03T14:42:59.320-08:002013-12-03T14:42:59.320-08:00I'm really very sorry it's taken me so lon...I'm really very sorry it's taken me so long to respond to your question. See the section on getting started, particularly: "Post to the mailing list and announce your interest in contributing, tell me a little about yourself. Read this blog, and try to use Mutability Detector".<br /><br />We can talk about how to get experience :)Graham Allanhttps://www.blogger.com/profile/16539618370362116733noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-43603157044115499962013-11-18T12:18:54.806-08:002013-11-18T12:18:54.806-08:00 i Want to join your project but do not have worki... i Want to join your project but do not have working exp in java.<br /><br />Please suggest how to startAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-61956082695740950612013-03-07T09:21:24.890-08:002013-03-07T09:21:24.890-08:00Hi Jc,
I've added a wiki page with download l...Hi Jc,<br /><br />I've added a wiki page with download links, since GitHub has deprecated the downloads page. The links are to the artifacts hosted on Maven Central, which you can just download from your browser. Hopefully that's not too close to Maven to put you off :)<br /><br />Link: https://github.com/MutabilityDetector/MutabilityDetector/wiki/Downloads<br /><br />Do let me know what you think.<br /><br />Regards,<br />GrahamGraham Allanhttps://www.blogger.com/profile/16539618370362116733noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-91702880707988341062013-03-07T05:39:58.780-08:002013-03-07T05:39:58.780-08:00Hi,
I just discovered your project and I'd li...Hi,<br /><br />I just discovered your project and I'd like to give it a try.<br />Could you update the download link here: https://github.com/MutabilityDetector/MutabilityDetector/downloads<br /><br />Because I don't want to use Maven :)<br /><br />Many thanks<br />JcAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-14784762964264510902012-10-21T13:03:57.432-07:002012-10-21T13:03:57.432-07:00Just to be pedantic, your MutableMischief is also ...Just to be pedantic, your MutableMischief is also immutable :)<br /><br />Although the return value of getLabel() is different from its superclass, it will always be the same for an instance of MutableMischief, just like a final field would be. To show what I mean, consider MutableMischief to be like this:<br /><br />public class MutableMischief extends Immutable {<br /><br /> @Override<br /> public String getLabel() {<br /> return "Return value keeps changing: " + (System.currentTimeMillis() % 10);<br /> }<br /><br /> public static void main(String args[]){<br /> MutableMischief mutObj= new MutableMischief();<br /> ImmutableClient immutClient= new ImmutableClient(mutObj);<br /> System.out.println(immutClient.printImmutableLabel());<br /> Thread.sleep(1000);<br /> System.out.println(immutClient.printImmutableLabel());<br /> }<br />}<br /><br />One of the times I ran this I got the result:<br /> Return value keeps changing: 6<br /> Return value keeps changing: 8<br /><br />So the issue is *not* that MutableMischief returns a different value than its superclass. It's that, on different invocations of the same method of the same instance of MutableMischief, different results are returned. It just so happens that having subclasses is a way to introduce that behaviour.<br /><br />Is that any clearer?<br /><br />Kind regards,<br />Graham<br /><br /><br />Graham Allanhttps://www.blogger.com/profile/16539618370362116733noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-57562648774662928112012-10-13T00:00:58.909-07:002012-10-13T00:00:58.909-07:00OK, I think this could be something like this:
cl...OK, I think this could be something like this:<br /><br />class Immutable{<br />private String label="Original Label";<br />public String <b>getLabel()</b>{<br />return label;<br />}<br />}<br /><br />public class MutableMischief extends Immutable{<br /><br />@Override<br />public String <b>getLabel()</b>{<br />return "Not Original Label";<br />}<br /><br />public static void main(String args[]){<br /><br />MutableMischief mutObj= new MutableMischief();<br />ImmutableClient immutClient= new ImmutableClient(mutObj);<br />System.out.println(<b>immutClient.printImmutableLabel()</b>);<br />}<br />}<br /><br /><br />class ImmutableClient{<br /><br />Immutable immutObj;<br /><br />ImmutableClient(Immutable immut){<br />this.immutObj=immut;<br />}<br /><br />public String printImmutableLabel(){<br />return <b>immutObj.getLabel();</b><br />}<br /><br />}<br /><br />The above program should print Original Label But it will print <b>Not Original Label</b>.<br /><br />Thanks...<br /><br /><a href="http://java-journal.blogspot.in/2012/06/string-pool-is-possible-due-to-string.html" rel="nofollow">String Pool is possible due to String Immutability </a>Rajinderhttps://www.blogger.com/profile/07874702857035374398noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-56126832370389204182012-10-12T16:07:48.695-07:002012-10-12T16:07:48.695-07:00Hi Rajinder,
Good catch. The subclass could use a...Hi Rajinder,<br /><br />Good catch. The subclass could use any field as the return value for getField(). It could either redeclare the field label, or introduce a new one, or return a random string. <br /><br />The point still stands that, because of subclassing, getField() could return different result on different calls.<br /><br />Make sense?<br /><br />Regards,<br />Graham Graham Allanhttps://www.blogger.com/profile/16539618370362116733noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-81988633259371667222012-10-12T08:01:08.651-07:002012-10-12T08:01:08.651-07:00private String label; in IAmImmutable class has p...private String label; in IAmImmutable class has private access. How can u change its value in sublcass by setLabel() method? It will give error:<br /><br />"label has private access in IAmImmutable".<br /><br />Thanks...Rajinderhttps://www.blogger.com/profile/07874702857035374398noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-80649383329177661812012-07-20T06:40:44.090-07:002012-07-20T06:40:44.090-07:00[wrote long comment, OpenID crapped out and ate it...[wrote long comment, OpenID crapped out and ate it, writing shorter version]<br /><br />Are you sure about AtomicReference? The rules mean that the store of the new TreeMap to the AtomicReference's value happens-before any load of the AtomicReference's value, but, i believe, have no bearing on the subsequent store of the AtomicReference to the ZoneRulesGroup.<br /><br />So, although you can only see the AtomicReference in a good state, you might not see it at all.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-60614321989035784742012-07-16T04:01:18.555-07:002012-07-16T04:01:18.555-07:00Fixed https://github.com/ThreeTen/threeten/commit/...Fixed https://github.com/ThreeTen/threeten/commit/60ad0f24569491ab44a26e929c6e6c7e26b62244Stephen Colebournehttps://www.blogger.com/profile/01454237967846880639noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-10640201867480102062011-10-01T11:58:33.156-07:002011-10-01T11:58:33.156-07:00Good ideas here. The killer use-case for me is in ...Good ideas here. The killer use-case for me is in testing. I'd like to assert in unit tests that my domain objects or data structures are either immutable or effectively immutable. Usually the goal is to assert the most strict form of immutability.Craighttps://www.blogger.com/profile/15806804843602653454noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-60049931930055933342011-07-09T02:30:03.789-07:002011-07-09T02:30:03.789-07:00That's something I've been thinking about,...That's something I've been thinking about, and a mechanism for tailoring the output of assert has been in place since 0.6. The default assert will be the most strict and the user will be able to supply suppressions. For example, for java.lang.String, you could write something like:<br /><br />assertInstancesOf(String.class, areImmutable(), allowing(field("hash").toBeReassigned());<br /><br />(don't quote me on the syntax, hopefully you get the idea)<br /><br />Something similar could be used for effectively immutable objects. The overall codebase would then have to be assessed manually, to check that publication was safe, but hopefully that would still be a helpful utility.<br /><br />Thanks Craig.Graham Allanhttps://www.blogger.com/profile/16539618370362116733noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-8700048189769880792011-07-08T14:58:03.671-07:002011-07-08T14:58:03.671-07:00That's exactly what I meant. A unit test could...That's exactly what I meant. A unit test could unsafely publish IAmImmutable and another thread could observe a null field.<br /><br />I didn't remember the term "effectively immutable" from JCIP. Discovering effectively immutable objects seems interesting, and difficult.<br /><br />I recommend splitting the API into assertEffectivelyImmutable() and assertImmutable(). JCIP says "Immutable objects, on the other hand, can be safely accessed even when synchronization is not used to publish the object reference." I think that assertImmutable() should be strict on that point.Craighttps://www.blogger.com/profile/15806804843602653454noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-3361870368191123892011-07-08T13:25:02.114-07:002011-07-08T13:25:02.114-07:00I'm not sure if I'm interpreting you corre...I'm not sure if I'm interpreting you correctly, but you're right, "Can't be extended" is definitely not the only rule. Classes which cannot be extended can be mutable. Yep, there's much more to it.<br /><br />In my example, I probably should have made the same distinction between Immutable and Effectively Immutable, as JCIP also does. In my example, IAmImmutable is the latter: once an instance of that class is safely published, it cannot be seen to change by clients of the class. <br /><br />However, if it is unsafely published to other threads, the lack of the final modifier would become an issue, as the field could be accessed before it has been assigned. Thus a client of the class could observe getLabel() returning null on the first call, then returning a non-null String on the second call. Safely publishing prevents this.<br /><br />At least, that's my understanding. If you could share a unit test or some other piece of code that demonstrates what you mean, I'd love to see it.Graham Allanhttps://www.blogger.com/profile/16539618370362116733noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-9991932792077196692011-07-08T13:09:34.712-07:002011-07-08T13:09:34.712-07:00Craig, I'll answer your first question too, th...Craig, I'll answer your first question too, then take another comment to answer your second points.<br /><br />Effective Java includes as one of its five rules for immutability "Ensure that the class can't be extended."<br /><br />See <a href="http://books.google.com/books?id=ka2VUBqHiWkC&pg=PA73&dq=%22ensure+that+the+class+can%27t+be+extended%22&hl=en&ei=32MXTojcJtGn8QOGjZER&sa=X&oi=book_result&ct=result&resnum=1&ved=0CCoQ6AEwAA#v=onepage&q=%22ensure%20that%20the%20class%20can%27t%20be%20extended%22&f=false" rel="nofollow">here (Google Books)</a>Graham Allanhttps://www.blogger.com/profile/16539618370362116733noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-73807523238873960412011-07-08T06:39:27.502-07:002011-07-08T06:39:27.502-07:00I'll go ahead an answer my own question. Effec...I'll go ahead an answer my own question. Effective Java does not say that an object is only immutable if it can't be extended, because that's not true. The requirements for immutability are quite precise and listed in Java Concurrency in Practice. According to the rules, IAmImmutable is NOT immutable because its field is non-final. If its field were final, it would be irrelevant if its subclasses were mutable, it would still be immutable no matter what. Even without writing a subclass or using crazy reflection, I can write a unit test which proves that IAmImmutable is in fact mutable.Craighttps://www.blogger.com/profile/15806804843602653454noreply@blogger.comtag:blogger.com,1999:blog-8656465666508353224.post-37567881153260934502011-07-07T22:39:12.023-07:002011-07-07T22:39:12.023-07:00Where in Effective Java does it say that an object...Where in Effective Java does it say that an object is only immutable if it can't be extended?Craighttps://www.blogger.com/profile/15806804843602653454noreply@blogger.com