Bug 101150
Summary: | ContentSection doesn't have a DomainObjectInstantiator | ||
---|---|---|---|
Product: | [Retired] Red Hat Enterprise CMS | Reporter: | Rafael H. Schloming <rafaels> |
Component: | other | Assignee: | Jon Orris <jorris> |
Status: | CLOSED WONTFIX | QA Contact: | Jon Orris <jorris> |
Severity: | high | Docs Contact: | |
Priority: | high | ||
Version: | nightly | CC: | goldfish, tross |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2006-09-05 17:56:53 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
Rafael H. Schloming
2003-07-29 16:56:23 UTC
Another thing I should note is that even if this is fixed the same instantiator will be registered multiple times (once for each SectionInitializer that is present in enterprise.init). Strange that it doesn't appear to affect the server. The duplicate registration shouldn't be a problem, as the root of the DomainObjectFactory impl is just a Map, and it'll overwrite the old object. Given that the following is a common pattern: setup.setInstantiator(new ACSObjectInstantiator() { public DomainObject doNewInstance(DataObject dataObject) { return new ContentSection(dataObject); } Perhaps this could be handled automatically by the DomainObjectFactory. Something like the following psuedo code: If instantiator is null if type is ACSObject registerInstantiator(type, new ACSObjectInstantiator() { public DomainObject doNewInstance(DataObject dataObject) { type.reflectionConstructor(dataObject) } else register a DomainObjectInstantiator My idea is essentially domain.ReflectionInstantiator, which isn't working anyhow. See IRC Log: <danpb> why exactly do we need to register instantiators for all these things ? <danpb> shouldn't the ReflectionInstantiator registered against ACSObject work ? <danpb> (for every thing that is an ACSObject only, of course) <danpb> you'd only need the custom instantiator if you MyObject(DataObject dobj) constructor wasn't public <jorris_home> danpb: Interesting. I didn't know about ReflectionInstantiator. rhs says it doesn't appear to be working for ContentSection <jorris_home> And it's constructor is public <danpb> hmm, that's odd * jorris_home looks at code... <jorris_home> It doesn't seem as though it's used that way. ReflectionInstantiator is used by ACSObject instantiator. <jorris_home> So it is used, indirectly. A specific type, say ContentSection, is mapped to an anonymous inner class of ACSObjectInstantiator, which may use ReflectionInstantiator. <jorris_home> But there doesn't appear, in my brief search, to be any logic in DomainObjectFactory that says: <jorris_home> if no instantiator for Type, try a ReflectionInstantiator. <danpb> no, that logic in in ACSObjectInstantiator <danpb> hmm <danpb> ok, what happens is thus: <danpb> DOF looks up instantiator for ContentSection <danpb> there isn't one, so it tries its super type <danpb> evenntually it comes across ACSObjectInstantiator <danpb> DOF then calls the resolveInstantiator method on this <danpb> this will return an instance of ReflectionInstantiator to do the work <danpb> i know this must be working (for some types at least) because I got an error in it the other day, when my constructor was brokenm <danpb> so maybe it is an instantiator registered to some type *between* ACSObject & ContentSection that's screwing things up <danpb> Application / Resource for example <jorris_home> Maybe. <jorris_home> I'm running tests locally to see. <rhs> It's possible, the exception is thrown on line 137 of DomainObjectFactory.java <rhs> That means that one of the calls to resolveInstantiator returned null. <rhs> What is truly screwed up about this is that depending on the type of the OID or DataObject at the time you pass it into DomainObjectFactory you will get different instantiators. <danpb> personally I think the resolverInstantiator bit is just 'smoking crack' <jorris_home> what is crack? <jorris_home> ccmbot: hello? <ccmbot> hi jorris_home <jorris_home> ccmbot: what is crack? <ccmbot> jorris_home: Sorry, I've no idea what 'crack' is. <danpb> once DOF gets an instantiator for a type it should call doNewInstance immediately <rhs> That still doesn't solve the problem. <danpb> no, just makes mee feel better ;-) <rhs> If I pass in an OID with an ACSObject type I'm going to get a different answer than if I pass in the same OID with a ContentSection type. <justin_> off topic but related: that resources are using ACSObjectInstantiator was never intended. resources have explicit modeling of type metadata, and they should use that. So, I'll probably add a ResourceInstantiator that knows to do the right thing and change ResourceSetup class to use it (but only after rc1). <jparsons> I agree with you Justin...I was thinking those same thoughts as I watch this thread... <jorris_home> 2003-07-29 14:06:33,506 [ main] WARN framework.BaseTestCase - com.arsdigita.cms.ContentSectionTest.testDeleteSection started <jorris_home> 2003-07-29 14:06:36,906 [ main] INFO domain.DomainObjectFactory - Instantiating [com.arsdigita.cms.ContentSection:{id=25005}] <jorris_home> 2003-07-29 14:06:36,906 [ main] DEBUG domain.DomainObjectFactory - Initial type ContentSection <jorris_home> 2003-07-29 14:06:36,906 [ main] DEBUG domain.DomainObjectFactory - Parent type Application <jorris_home> 2003-07-29 14:06:36,906 [ main] DEBUG domain.DomainObjectFactory - Parent type Resource <jorris_home> 2003-07-29 14:06:36,906 [ main] DEBUG domain.DomainObjectFactory - Parent type ACSObject <jorris_home> 2003-07-29 14:06:36,907 [ main] DEBUG domain.DomainObjectFactory - Final type ACSObject <jorris_home> 2003-07-29 14:06:36,907 [ main] DEBUG domain.DomainObjectFactory - Found instantiator com.arsdigita.kernel.ACSObjectInstantiator@5ebee883 <jorris_home> 2003-07-29 14:06:36,908 [ main] DEBUG domain.DomainObjectFactory - Initial delegate com.arsdigita.kernel.ACSObjectInstantiator@5ebee883 <jorris_home> 2003-07-29 14:06:36,908 [ main] DEBUG kernel.ACSObjectInstantiator - Resolving type com.arsdigita.cms.ContentSection <jorris_home> 2003-07-29 14:06:36,908 [ main] DEBUG domain.DomainObjectFactory - Initial type ContentSection <jorris_home> 2003-07-29 14:06:36,908 [ main] DEBUG domain.DomainObjectFactory - Parent type Application <jorris_home> 2003-07-29 14:06:36,908 [ main] DEBUG domain.DomainObjectFactory - Parent type Resource <jorris_home> 2003-07-29 14:06:36,908 [ main] DEBUG domain.DomainObjectFactory - Parent type ACSObject <jorris_home> 2003-07-29 14:06:36,909 [ main] DEBUG domain.DomainObjectFactory - Final type ACSObject <jorris_home> 2003-07-29 14:06:36,909 [ main] DEBUG domain.DomainObjectFactory - Found instantiator com.arsdigita.kernel.ACSObjectInstantiator@5ebee883 <jorris_home> 2003-07-29 14:06:36,909 [ main] DEBUG kernel.ACSObjectInstantiator - Found instantiator: com.arsdigita.kernel.ACSObjectInstantiator@5ebee883 class com.arsdigita.kernel.ACSObjectInstantiator <jorris_home> 2003-07-29 14:06:36,909 [ main] DEBUG kernel.ACSObjectInstantiator - Getting reflection instantiator for null <jorris_home> 2003-07-29 14:06:36,930 [ main] WARN domain.ReflectionInstantia <kdykeman> richardl_home: sounds good. In the meantime, I'll try to introduce myself around a bit. <justin_> what happened between parent traversal one and two? <rhs> another piece to add to the puzzle, the getRegisteredInstantiator(String) does something completely different from the getRegisteredInstantiator(ObjectType). <jorris_home> justin_: parent traversal 2 is the ACSOjbectInstatiator calling DomainObjectInstantiator.getInstantiator. <rhs> The former looks up the ObjectType corresponding to the String and then delegates to getInstantiator <jorris_home> The null is suggesting that for the object type, the defaultDomainClass is null <rhs> The latter simply looks directly in the s_instantiators HashMap. <rhs> One of them has to be wrong. <rhs> Although this shouldn't really matter since my grep indicates we never call the String version, and my guess is the other version is the correct one. <danpb> rhs: doh, looks like a typo in getRegisteredInstantiator(String) - its delegating to the wrong method <danpb> its calling getInstantiator(ObjectType) instead of getRegisteredInstantiator(ObjectType) <rhs> I'll fix it. <rhs> Ok, it's fixed. <rhs> @34073 <jorris_home> Ok, I think I see the problem. <jorris_home> 2003-07-29 14:19:18,634 [ main] WARN domain.ReflectionInstantiator - cannot create reflection instantiator for null <jorris_home> java.lang.NullPointerException <jorris_home> at java.lang.Class.forName1(Native Method) <jorris_home> at java.lang.Class.forName(Class.java(Compiled Code)) <jorris_home> at com.arsdigita.domain.ReflectionInstantiator.<init>(ReflectionInstantiator.java:74) <jorris_home> at com.arsdigita.domain.ReflectionInstantiator.getInstantiator(ReflectionInstantiator.java:55) <jorris_home> at com.arsdigita.kernel.ACSObjectInstantiator.resolveInstantiator(ACSObjectInstantiator.java:148) <jorris_home> at com.arsdigita.domain.DomainObjectFactory.newInstance(DomainObjectFactory.java:130) <jorris_home> at com.arsdigita.kernel.Resource.retrieveResource(Resource.java:150) <jorris_home> at com.arsdigita.kernel.Resource.makeResource(Resource.java:92) <jorris_home> at com.arsdigita.kernel.Resource.createResource(Resource.java:66) <jorris_home> at com.arsdigita.web.Application.legacyMake(Application.java:168) <jorris_home> In Resource.makeResource, it sets the objectType for the DataObject, but not the defaultDomainClass. <jorris_home> The dataObject gets passed to the resolvers, and ends up in the ACSObjectResolver, which tries to create a reflectioninstnatiator, which needs the defaultDomainClass. <danpb> i was never really clear on why Resource had to manufacture its own DataObjects in this way rather than using the no-arg/ObjectType/String constructor like every other domain object in the system <rhs> It's because DOF has no generic create functionality. <rhs> So it needs to manually create the data object and then use DOF to retrieve it. <justin_> IOW, ecm had generic create-new-app code, which needed to be able to do App.createApp(c.a.App) <danpb> but the Resource has the ResourceType, which in turn has the domain class type <danpb> so it could use reflection to run the appropriate constructor <rhs> ResourceType only has the data object type, not the domain class. <danpb> hmm, that's a PITA The change 34073 should be backported to 5.2 & 6.0 merged on 6.0.x (38304) and 5.2.x (39045) QA_READY has been deprecated in favor of ON_QA. Please use ON_QA in the future. Moving to ON_QA. Closing old tickets |