May that can help. If someone wants to review it. Jean-Louis
---------- Forwarded message ---------- From: Jean-Louis MONTEIRO (JIRA) <j...@apache.org> Date: 2012/9/13 Subject: [jira] [Updated] (OWB-703) getBeans cache key algorithm must be unique To: dev@openwebbeans.apache.org [ https://issues.apache.org/jira/browse/OWB-703?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel] Jean-Louis MONTEIRO updated OWB-703: ------------------------------------ Attachment: OWB-703-2nd-shoot.patch Here is another proposal > getBeans cache key algorithm must be unique > ------------------------------------------- > > Key: OWB-703 > URL: https://issues.apache.org/jira/browse/OWB-703 > Project: OpenWebBeans > Issue Type: Bug > Affects Versions: 1.1.4, 1.1.5 > Environment: OWB 1.1.4, Codi 1.0.5, MyFaces 2.0.13, Tobago 1.5.7 > Reporter: Udo Schnurpfeil > Assignee: Mark Struberg > Priority: Critical > Fix For: 1.1.6 > > Attachments: OWB-703-2nd-shoot.patch, OWB-703-hash-cache-as-integer.patch, owb-703.patch > > > Our application was tested in a Pre-Production environment, and it turns out a problem which occurs sometime after 2 weeks but sometimes after a short time: > [9/11/12 10:46:27:288 CEST] 0000009e ServletWrappe E SRVE0068E: Uncaught exception thrown in one of the service methods of the servlet: > FacesServlet. Exception thrown : java.lang.IllegalArgumentException: Given bean type : class org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation.ViewAccessConversationExpirationEvaluatorRegistry is not applicable for the bean instance : BereitstellungModelLoaderImpl, Name:BereitstellungModelLoader, WebBeans Type:MANAGED, API Types:[java.lang.Object,de.nordlbit.iopc.optionen.jsf.model.BereitstellungModelLoader,de.nordlbit.iopc.optionen.jsf.model.BereitstellungModelLoaderImpl,java.io.Serializable], Qualifiers:[javax.inject.Named,javax.enterprise.inject.Any,javax.enterprise.inject.Default] > at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:923) > at org.apache.webbeans.container.InjectableBeanManager.getReference(InjectableBeanManager.java:133) > at org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils.getContextualReference(CodiUtils.java:215) > at org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils.getContextualReferenceByClass(CodiUtils.java:179) > at org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils.getContextualReferenceByClass(CodiUtils.java:139) > at org.apache.myfaces.extensions.cdi.jsf.impl.util.ConversationUtils.postRenderCleanup(ConversationUtils.java:668) > at org.apache.myfaces.extensions.cdi.jsf2.impl.listener.phase.CodiLifecycleWrapper.render(CodiLifecycleWrapper.java:128) > at javax.faces.webapp.FacesServlet.service(FacesServlet.java:191) > at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1213) > [...] > I think the reason is, that two objects got the same key in the map. > So we got wrong objects. > After this exception the application must be restarted, no request works anymore. > How can this happen? > Problem number 1: > Looking in the implementation: > There will be computed a key of type Long from all given parameters. > Parameters: injectionPointType, bdaBeansXMLPath, qualifiers > In practice we have one "injectionPointType" (say t) and one "qualifiers" (say q) and the computed hash code will be: > key = hash(t) + 29 * hash(q) > assume: hash(t)=1000 and hash(q)=100 > we got a key of 1000 + 29 * 100 = 3900 > but that's the same like > 1029 + 29 * 99 = 3900 > 1058 + 29 * 98 = 3900 > 1087 + 29 * 97 = 3900 > and so on. > If we got parameter with hash(t)=1029 and hash(q)=99 we have found 2 beans with the same key. > With that our map is broken, because the 2nd bean will remove the 1st bean while adding (with the same key). > Problem number 2: > Hash codes are generally not suitable to be used as keys because there are not unique. > The JavaDoc of the Object.hashCode() method says: > "It is not required that if two objects are unequal according to the equals(Object) method, > then calling the hashCode method on each of the two objects must produce distinct integer results." > The strings "org.apache.kcmdjx" and "java.lang.Object" have the same hash code (at least in my Apple java VM). > Solution: > I see 3 solutions here: > Solution 1: > Do the same like in 1.1.3: Build a String with all information inside. > Disadvantage: slow > Solution 2: > Create an helper object, which contains the unconverted information analog to e.g.: org.apache.myfaces.tobago.internal.context.ClientPropertiesKey > This will be faster than string concatenation, but there is to create an object as well. > Solution 3: > Using a map which can handle more than one key. > E. g. org.apache.commons.collections.map.MultiKeyMap -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira