You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openwebbeans.apache.org by "Udo Schnurpfeil (JIRA)" <ji...@apache.org> on 2012/09/11 19:58:07 UTC

[jira] [Commented] (OWB-703) getBeans cache key algorithm must be unique

    [ https://issues.apache.org/jira/browse/OWB-703?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13453233#comment-13453233 ] 

Udo Schnurpfeil commented on OWB-703:
-------------------------------------

By the way: Is it guarantied, that the order of the qualifiers are always the same? If not, the implementation have to consider that (1.1.3 doesn't).
                
> 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
>            Priority: Critical
>
> 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