Comment obtenir la reconnaissance du bogue hashCode () de l’URI Java qui a été refusé de manière inappropriée

Un élément fondamental du contrat d’ Object Java est que la hashCode() doit être cohérente avec la méthode equals() . Cela a du sens et est facile à comprendre: si deux objects sont “égaux” d’une manière ou d’une autre, ils devraient renvoyer le même code de hachage. Dans le cas contraire, vous pouvez par exemple placer un object dans un HashSet , puis vérifier ultérieurement si une instance distincte fait partie de l’ensemble et récupérer incorrectement la valeur false , même si la méthode equals() aurait considéré les objects comme équivalents.

En fait, le code URI de Java a ce problème à partir de Java 6. Essayez ce code:

 import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import java.net.URI; import org.junit.Test; public class URITest { @Test public void testURIHashCode() { final URI uri1 = URI.create("http://www.example.com/foo%2Abar"); final URI uri2 = URI.create("http://www.example.com/foo%2abar"); assertThat("URIs are not equal.", uri1, equalTo(uri2)); assertThat("Equal URIs do not have same hash code.", uri1.hashCode(), equalTo(uri2.hashCode())); } } 

Les séquences d’échappement URI, conformément à la RFC 3968, sont insensibles à la casse; c’est-à-dire que %2A et %2a sont considérés comme équivalents. L’ URI.equals() Java URI.equals() en tient compte. Cependant, l’ URI.hashCode() n’en tient pas compte! Cela signifie que deux instances d’URI qui retournent true pour URI.equals() peuvent néanmoins renvoyer des codes de hachage différents, comme illustré dans le code ci-dessus!

J’ai soumis ce problème, qui aurait abouti au bogue Java 7134993, mais ce bogue n’est plus disponible. Le même problème, cependant, est présenté dans le bogue Java 7054089 . (Je ne sais pas si cela provient de ma soumission ou de quelqu’un d’autre, mais le problème est le même.) Cependant, l’évaluation a nié le bogue: “Les exemples cités sont des URI opaques et les parties spécifiques du schéma ne sont donc pas analysé. “

Quiconque a évalué ce bogue ne doit pas avoir compris ce que cela signifie pour equals() et hashCode() pour être cohérent. Le contrat pour Object.equals() indique clairement: “Si deux objects sont égaux selon la méthode equals (Object), l’appel de la méthode hashCode sur chacun des deux objects doit produire le même résultat entier.” Notez l’utilisation de “must”, pas “devrait”.

Le point ici est que, même si l’évaluateur prétend que l’URI est “opaque” et “non analysé”, la mise en œuvre de URI.equals() (contrairement à ses affirmations) parsing effectivement l’URI et tient compte de l’insensibilité à la casse. . L’ URI.hashCode() ne l’est pas.

Alors, suis-je complètement dense ici et manque quelque chose d’évident? Si je le suis, veuillez éclaircir mon erreur et je marquerai votre réponse comme correcte. Sinon, la question est la suivante: maintenant que Sun / Oracle ne semble plus autoriser les commentaires sur les bogues classés, quel recours ai-je pour obtenir une reconnaissance et une action sur ce problème fondamental dans l’implémentation en Java de l’identificateur principal d’Internet, l’URI?

Je soumettrais à nouveau un bogue contre Java 1.7.0_17 en utilisant l’exemple que vous donnez ici plutôt que celui du bogue 7054089. J’ai vérifié que votre exemple StackOverflow était également valable pour cette version. J’ai entendu dire qu’Oracle avait résolu la résolution des bugs sur Java 6, à l’exception des problèmes de sécurité.

Dans votre soumission de bogue d’origine, les URI que vous avez fournis sont des URI opaques qui ont peut-être jeté l’évaluateur. Et je pense que vous voulez dire RFC 2396.

En outre, vous pourriez avoir un nouvel évaluateur 🙂

Il me semble qu’ils ont définitivement rompu le contrat pour hashCode () ici.

Et c’est dommage qu’ils n’aient pas de mécanisme de commentaire comme Java pour StackOverflow (ou les commentaires de base comme ils le faisaient auparavant).

Bonnes nouvelles! Oracle semble avoir corrigé ce bogue pour Java 8 dans JDK-7171415 ! J’ai vérifié que mon test ci-dessus passe maintenant en Java 1.8.0_92 sur Windows 10 Pro 64 bits. Le nouveau ticket de bogue ne fait référence à aucun des précédents, donc je ne sais pas comment c’est arrivé. Mais je suis content qu’ils aient finalement résolu le problème.