tag:blogger.com,1999:blog-741750605858169835.post8870369878830855134..comments2024-01-24T14:53:02.919+00:00Comments on Stephen Colebourne's blog: Annotating JDK default dataStephen Colebournehttp://www.blogger.com/profile/01454237967846880639noreply@blogger.comBlogger26125tag:blogger.com,1999:blog-741750605858169835.post-54988707112084815652015-12-29T00:14:11.576+00:002015-12-29T00:14:11.576+00:00I don't know if it's correct to say that i...I don't know if it's correct to say that it's 100% safe just because it doesn't use the default locale. Sometimes using Locale.ROOT by default is the bug.<br />Unknownhttps://www.blogger.com/profile/15686538495254349818noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-77170623118774444522013-02-11T21:59:34.028+00:002013-02-11T21:59:34.028+00:00Hi, the Lucene forbidden API checker was forked an...Hi, the Lucene forbidden API checker was forked and released as Ant, Maven or CLI task at https://code.google.com/p/forbidden-apis/, available via Maven Central.Uwe Schindlerhttps://www.blogger.com/profile/08079070589736993766noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-76240812609751217942013-01-18T22:04:17.869+00:002013-01-18T22:04:17.869+00:00Thus the annotation is useful, not as compiler war...Thus the annotation is useful, not as compiler warning like Deprecated, but useful for and IDE to either flag or resort the possibly choices. <br /><br />To the point of using @Deprecated. No, the idea is NOT that you should never use these calls and that there is something new and improved, but that such a call has some limitations. Many of the more explicit calls where designed at the same time as no arg version, so deprecated suggests something that is not true.<br /><br />Maybe a lesson for API developers is that a call that can assume defaults might be better represented as an API that allows nulls for certain arguments, or require a call to the pass the actual system default (Timezone.getDefault() etc.) than a version that has NO or fewer args.<br /><br />System properties for the whole server is NOT always the answer. Sometimes it is a problem of the data comes from users with different locales.<br /><br />P.A.H.https://www.blogger.com/profile/06980984031872519050noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-77161543552715868112013-01-18T21:52:41.114+00:002013-01-18T21:52:41.114+00:00Annotations need not take Strings, they could take...Annotations need not take Strings, they could take a class name. I don't know if that would apply in a yet designed @DependsOnP.A.H.https://www.blogger.com/profile/06980984031872519050noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-68278776636404397632012-12-16T14:26:23.475+00:002012-12-16T14:26:23.475+00:00That's good news, Uwe, I'll keep an eye on...That's good news, Uwe, I'll keep an eye on your blog.hertzsprunghttps://www.blogger.com/profile/17692467375354355165noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-80244317296356753682012-12-14T09:44:42.589+00:002012-12-14T09:44:42.589+00:00Hi,
the tool that is used by Lucene to detect thos...Hi,<br />the tool that is used by Lucene to detect those names (the list with signatures above comes from our tool) can also be used to "disallow/forbid" those signatures, in fact, the Lucene SVN also contains a second signature file containing those methods: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/tools/forbiddenApis/executors.txt?view=markup<br /><br />I am planning to release the tool as a custom ANT or Maven plugin (currently we only have a ANT version available). It is configureable with own signature lists. See my blog about this. We run the check after compiling our code on the bytecode of the generated classes.Uwe Schindlerhttps://www.blogger.com/profile/08079070589736993766noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-13633939475107826522012-12-14T09:35:51.977+00:002012-12-14T09:35:51.977+00:00Hi:
"2) I didn't check all of them, but ...Hi:<br /><br />"2) I didn't check all of them, but (almost?) every method on the list has an overloaded method with Locale as a parameter. So for a developer it ought to be obvious that if they don't pass a Locale, Java will have to somehow figure out a "default" value for it."<br /><br />The problem here is that e.g. IDEs like eclipse always provide the simpliest method signature to the user (e.g. Eclipse never offers String.toLowerCase(Locale) by itsself). This leads to code horrible broken in the Turkish Locale.Uwe Schindlerhttps://www.blogger.com/profile/08079070589736993766noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-31865342831730897792012-12-10T19:18:15.157+00:002012-12-10T19:18:15.157+00:00Probably a bit late now, but it would have been po...Probably a bit late now, but it would have been possible to implement a custom FindBugs detector that used ASM and thus leveraged existing build infrastructure (ant/maven/etc). Taking it one step further, if there's a precedence for this check in FindBugs, it might be nice to coordinate with the FindBugs team to have it included by default.Graham Allanhttps://www.blogger.com/profile/16539618370362116733noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-29074163350927542342012-12-07T18:43:54.259+00:002012-12-07T18:43:54.259+00:00I don't get it:
1) all defaults can be set wi...I don't get it:<br /><br />1) all defaults can be set with system properties + for Locale & TimeZone there are also specific methods to set the default. So for server-side applications you can easily force the defaults you want.<br /><br />2) I didn't check all of them, but (almost?) every method on the list has an overloaded method with Locale as a parameter. So for a developer it ought to be obvious that if they don't pass a Locale, Java will have to somehow figure out a "default" value for it.<br /><br />3) what if Java gets default parameters some day? Annotate every such method with @DependsOnDefaultValuesOfParametersWhenNotGiven?<br /><br />So can someone explain me what all the fuss is about?Anthonynoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-74626931972339893462012-12-06T14:40:56.694+00:002012-12-06T14:40:56.694+00:00Good idea. In a similar vein, I'd love to see...Good idea. In a similar vein, I'd love to see compiler/tool support for recognising when you've created a thread or thread pool with a default name. Having usefully-named threads makes diagnosis with VisualVM so much less painful.hertzsprunghttps://www.blogger.com/profile/17692467375354355165noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-80060630159462909422012-12-05T22:44:13.300+00:002012-12-05T22:44:13.300+00:00"Given, that these methods are perfectly fine..."Given, that these methods are perfectly fine for a client-side application"<br /><br />This is not always true! A client application is also affected by this! Default charsets and Locales should only be used when the user opens the file from his local filesystem or when you present some formatted text to the user. But this is not true for another very common case - the best example I can give is listed in my own blog post about this (referred to by Stephen): Your application may ship with some text-file resource inside the JAR file (e.g. in Lucene those are language specific stop word files), that is read using Class#getResourceAsStream() wrapped by a Reader without charset. In this case, you are the provider of the resource file inside your application's JAR file and so *you* define the charset! The default charset is in 99% of all cases the wrong one! Uwe Schindlerhttps://www.blogger.com/profile/08079070589736993766noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-86932008873463660862012-12-05T17:37:43.829+00:002012-12-05T17:37:43.829+00:00The obvious choice would be to use an enum for tha...The obvious choice would be to use an enum for that. But, because enums are final and annotations can't be used with a type parameter, said enum could only be extended by the JDK developers. The concept of a @DependsOn annotation is IMHO so useful, that application developers should be able to introduce application-specific categories.<br />Besides, @SupressWarnings takes a String, too, and there don't seem to be too many complaints about this fact.Frisianhttps://www.blogger.com/profile/03637182846094377541noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-20019874761942843972012-12-05T14:35:26.422+00:002012-12-05T14:35:26.422+00:00I agree that the constructor is affected. By this ...I agree that the constructor is affected. By this point I meant only to indicate that the annotation may be misleading. Consider the annotation on String.toLowerCase() and on DateFormat.getInstance(). In the former case, the annotation seems to apply because of what state the method changes. In the latter case, the annotation seems to apply because of what value the method returns. In actuality, the annotation applies in both cases because each method calls (either directly or indirectly) a variant of Locale.getDefault. I think it's the "depends on" wording that gives me some hesitation. Maybe something like @ObtainsJdkDefault could be more narrowly interpreted.Nathannoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-79407631390486302992012-12-05T14:30:33.622+00:002012-12-05T14:30:33.622+00:00I wouldn't consider this annotation to be like...I wouldn't consider this annotation to be like checked exceptions. It is additional info provided for use. It would be totally up to applications whether they apply the annotation to their own code. I don't see the JDK trying to pass the info on.<br /><br />I'm not a fan of string based annotations here either. The string is a magic constant that developers have to learn and is not directly compile time checked.Stephen Colebournehttps://www.blogger.com/profile/01454237967846880639noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-79314217201841257412012-12-05T14:18:54.230+00:002012-12-05T14:18:54.230+00:00You are correct. I was mistaking Character.toLower...You are correct. I was mistaking Character.toLowerCase for String.toLowerCase, which are not generally equivalent, of course. Still, the point stands that such an annotation on an implementing or overriding method is effectively lost if the overridden method is virtually invoked. This kind of transitivity is more difficult to discover than it is for other effect annotations like checked exceptions, because the same notion of covariance does not apply.Nathannoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-74774256639210149432012-12-05T09:40:40.535+00:002012-12-05T09:40:40.535+00:00(3): This is not true, see javadocs: CASE_INSENSIT...(3): This is not true, see javadocs: CASE_INSENSITIVE_ORDER - A Comparator that orders String objects as by compareToIgnoreCase -> referring to -> Compares two strings lexicographically, ignoring case differences. This method returns an integer whose sign is that of calling compareTo with normalized versions of the strings where case differences have been eliminated by calling Character.toLowerCase(Character.toUpperCase(character)) on each character. Note that this method does not take locale into account, and will result in an unsatisfactory ordering for certain locales. The java.text package provides collators to allow locale-sensitive ordering.<br /><br />So this constant/method is 100% safe and works as if it would use Locale.ROOT (which uses the string lowercasing implied by locale-independent char-by-char lowercasing, e.g. also implemented by Lucene's LowerCase text analysis filters). Please note: There is no Locale-based character lowercasing, locales only affect strings. Because of this lowercasing every single char is totally different to lowercasing a string (which is another confusing thing for beginners).Uwe Schindlerhttps://www.blogger.com/profile/08079070589736993766noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-2812480193806933052012-12-05T09:33:31.368+00:002012-12-05T09:33:31.368+00:00@Stephen: JEP is also fine, I just don't know ...@Stephen: JEP is also fine, I just don't know all those terms. From my perspective it has to go through some standardization gremium and that's the biggest issue here.<br /><br />@Nathan: "The information implied by the annotation may be misleading. For example, many constructors of Formatter are on the list, because they obtain the default locale." -> From my perspective the ctor is still affected because it returns to you an instance of Formatter that is depending on default locale, so it is affected by default locale, just not direct but indirect. Unless you have a separate subclass like DefaultLocaleFormatter which has all methods marked as unsafe, this is the only way to mark those APIs.<br /><br />@Frisian: I would be happy if PMD or FindBugs would check for this correctly, but unfortunately their support for dsetecting this type of problems is horrible incomplete. This is why Lucene implemented its own checker as ANT task using bytecode analysis which is horribly fast (and a MAVEN task is also available by some 3rd party people that forked our code). With the introduction of the annotation this byte code analysis could be extended to go away from static lists, but instead just check for annotations on every invoke VM instruction.Uwe Schindlerhttps://www.blogger.com/profile/08079070589736993766noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-83804956885526814472012-12-04T20:07:00.105+00:002012-12-04T20:07:00.105+00:00Great idea, but it seems wasteful to use it for JD...Great idea, but it seems wasteful to use it for JDK defaults only. You are basically talking about a kind of method effect annotation. Frisian in the comment above had suggested @DependsOn("JdkDefault"), but more correct and fully generic form should be more like @DependsOn("Locale.default"), @DependsOn("TimeZone.default") or @DependsOn("Locale.default", "TimeZone.default", ...), etc using the appropriate "import" information from the source file to shorten the package names. One should be able to use this annotation for defaults in other frameworks and to otherwise annotate method's dependence on a mutable static variables.<br /><br />However, just like with other effects annotations (and as with "throws" which is also a special kind of effects annotation) there is a scalability problem. Checked exceptions and "throws" somewhat work around this problem by providing a way of handling exception and/or wrapping them into other types of exceptions. Even though checked exceptions are a powerful and very helpful tool in skillful hands precisely because they can be used as an effect annotation tool that is being enforced by compiler, they still invoke a lot of criticism from many people.<br /><br />One should figure first how the corresponding scalability problem should be addressed before implementing any kind of @DependsOn annotation.elizarovhttps://www.blogger.com/profile/06339534234190675498noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-68975690121987633842012-12-04T18:54:33.506+00:002012-12-04T18:54:33.506+00:00Given, that these methods are perfectly fine for a...Given, that these methods are perfectly fine for a client-side application, wouldn't it be enough to check them with PMD or Checkstyle? The JDK's source code is available and I don't think that a lot locale-dependent methods will be added to it in the future.<br />I like the annotation, though. But I'd like to see a more generic variant: @DependsOn("JdkDefaults")Frisianhttps://www.blogger.com/profile/03637182846094377541noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-13354669181447858262012-12-04T18:03:41.227+00:002012-12-04T18:03:41.227+00:00Three potential issues:
(1) The annotation indica...Three potential issues:<br /><br />(1) The annotation indicates that zero or more paths may be default dependent, not that all paths are default dependent. In this way it may be overly safe. Some checked exceptions suffer from this. (MalformedURLException comes to mind.)<br /><br />(2) The information implied by the annotation may be misleading. For example, many constructors of Formatter are on the list, because they obtain the default locale. However, the default locale is not *used* by these constructors. It is the methods of such an instance of formatter that have potentially unsafe behavior.<br /><br />(3) The information implied by the annotation may be lost by certain abstractions. For example, String.CASE_INSENSITIVE_ORDER.compare(String, String) depends on String.toLowerCase(). Transitively, String.CASE_INSENSITIVE_ORDER.compare(String, String) is default dependent. Transitively, anything that invokes String.CASE_INSENSITIVE_ORDER.compare(String, String) is default dependent. However, the latter dependency may not be knowable, since the type of the instance of Comparator may not be knowable.Nathannoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-33674882573322203402012-12-04T14:23:26.065+00:002012-12-04T14:23:26.065+00:00@Uwe, the JCP isn't really relevant here. Its ...@Uwe, the JCP isn't really relevant here. Its mostly a rubber stamping body on Java SE matters. It certainly doesn't initiate ideas. This needs to go into the OpenJDK processes if its going to happen. It needs a JEP and a plan for JDK1.9.Stephen Colebournehttps://www.blogger.com/profile/01454237967846880639noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-472396991522900312012-12-04T14:11:04.913+00:002012-12-04T14:11:04.913+00:00@Anonymous: The method list FindBugs is on is not ...@Anonymous: The method list FindBugs is on is not complete (it in fact only catches the most common ones). We investigated FindBugs and PMD at Lucene; but then moved to the 100 times faster ASM based checker with a full-featured charset/locale/TZ list. We were also able to disable other horrible code patterns like printStackTrace().Uwe Schindlerhttps://www.blogger.com/profile/08079070589736993766noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-74156668716917247662012-12-04T14:06:21.644+00:002012-12-04T14:06:21.644+00:00FWIW, Findbugs issues a warning when using the def...FWIW, Findbugs issues a warning when using the default charset (http://findbugs.sourceforge.net/bugDescriptions.html#DM_DEFAULT_ENCODING) - I don't think it does anything for default locale / timezone.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-85258077656015728372012-12-04T13:41:53.466+00:002012-12-04T13:41:53.466+00:00@Robert: Unfortunately @Deprecated must also be co...@Robert: Unfortunately @Deprecated must also be communicated through JCP...Uwe Schindlerhttps://www.blogger.com/profile/08079070589736993766noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-65497099584105406842012-12-04T13:37:22.632+00:002012-12-04T13:37:22.632+00:00A great annotation for these methods already exist...A great annotation for these methods already exists: @Deprecated<br />Robert Muirhttps://www.blogger.com/profile/09219569681268881437noreply@blogger.com