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

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

Computing the hash code in the constructor is a good idea for this class! The 
code is thread save automatically.
But I would keep the hash code computation in a separate method to keep the 
code clean and comprehensible.
                
> 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

Reply via email to