api's, factories and services
by Mark Proctor
Just a reminder when doing api's
Stage interfaces in internal-api and make sure you do factories for
them, almost never expose "new" constructors to users. We provide both
static factories and a service registry, and we ideally should continue
to support both. i.e. we have
KnowledgeBuilderFactory (static method factory, actually wraps below)
KnowledgeBuilderFactoryService (singleton service)
static example:
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder()
singleton service exmaple:
KnowledgeBuilderFactoryService kbuilderfs =
ServiceRegistry.getInstance().get( KnowledgeBuilderFactoryService.class )
KnowledgeBuilder kbuilder = kbuilderfs .newKnowledgeBuilder()
All of our factory services should be registered in
org.drools.util.ServiceRegistryImpl, this has delegation to say OSGi if
it exists (via the service locator pattern). So we become much more
friendly to OSGi or other container environments that are service
locator oriented.
"new" should almost never be used, apart from when construcing say
default or debug listener implementations.
Mark
12 years, 10 months
BUG: [5.3.0.Final] CollectSetAccumulateFunction should probably use IdentityHashMap internally
by SirMungus
[First post. I apologize in advance if I'm following the wrong protocol to
report a bug.]
I had a rule using the collectSet() accumulator that was giving me an NPE at
line 123 of CollectSetAccumulateFunction.java, highlighted below:
public void reverse(Serializable context,
Object value) throws Exception {
CollectListData data = (CollectListData) context;
CollectListData.MutableInt counter = data.map.get( value );
*/if( (--counter.value) == 0 ) {/*
data.map.remove( value );
}
}
When looking in the debugger, I could see that the "value" passed in was
indeed present within the "data.map". However, the "data.map.get(value)" was
returning null. I thankfully realized this was because the object had
changed, which changed its hashCode(). The stored hashCode() in the HashMap
was different from its current hashCode().
I solved my problem by reimplementing my hashCode() as
System.identityHashCode(this) and my equals as "this == other".
However, I suspect the CollectSetAccumulateFunction should really use an
IdentityHashMap in this situation. It's a really bad idea to allow mutable
objects as keys in HashMap, and there is nothing about the collectSet()
accumulator function that suggests that it should only collect immutable
objects.
Thanks.
P.S. I'm loving Drools. Great tool.
--
View this message in context: http://drools.46999.n3.nabble.com/BUG-5-3-0-Final-CollectSetAccumulateFun...
Sent from the Drools: Developer (committer) mailing list mailing list archive at Nabble.com.
12 years, 10 months