| Summary: | Can not get long id from external ID types. | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Modeling] EMF | Reporter: | Stephane fournier <stephane.fournier> | ||||
| Component: | cdo.core | Assignee: | Eike Stepper <stepper> | ||||
| Status: | CLOSED WORKSFORME | QA Contact: | Eike Stepper <stepper> | ||||
| Severity: | normal | ||||||
| Priority: | P3 | CC: | stefan.schalomon, stefan, stepper | ||||
| Version: | 4.2 | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Windows XP | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
|
Description
Stephane fournier
The stack trace implies that a CDOObject has been assigned an external ID, which should be impossible. The question is what leads to this malicious LoadRevisionsRequest. Can you set a breakpoint in LoadRevisionsRequest.requesting(CDODataOutput) and paste the stack trace here? (In reply to comment #1) > The stack trace implies that a CDOObject has been assigned an external ID, > which should be impossible. The question is what leads to this malicious > LoadRevisionsRequest. Can you set a breakpoint in > LoadRevisionsRequest.requesting(CDODataOutput) and paste the stack trace here? In LoadRevisionsRequest.requesting(CDODataOutput), ids : [oid:2da551b-0614-4818-ae9f-0aa5f51c7772] fetchRules for these ids == null. Stack trace : LoadRevisionsRequest.requesting(CDODataOutput) line: 126 LoadRevisionsRequest(CDOClientRequest<RESULT>).requesting(ExtendedDataOutputStream) line: 66 LoadRevisionsRequest(RequestWithConfirmation<RESULT>).doExtendedOutput(ExtendedDataOutputStream) line: 117 LoadRevisionsRequest(Signal).doOutput(BufferOutputStream) line: 296 LoadRevisionsRequest(RequestWithConfirmation<RESULT>).doExecute(BufferInputStream, BufferOutputStream) line: 102 LoadRevisionsRequest(SignalActor).execute(BufferInputStream, BufferOutputStream) line: 51 LoadRevisionsRequest(Signal).runSync() line: 251 CDOClientProtocol(SignalProtocol<INFRA_STRUCTURE>).startSignal(SignalActor, long) line: 396 LoadRevisionsRequest(RequestWithConfirmation<RESULT>).doSend(long) line: 87 LoadRevisionsRequest(RequestWithConfirmation<RESULT>).send() line: 73 CDOClientProtocol.send(RequestWithConfirmation<RESULT>) line: 397 CDOClientProtocol.send(LoadRevisionsRequest) line: 430 CDOClientProtocol.loadRevisions(List<RevisionInfo>, CDOBranchPoint, int, int) line: 160 DelegatingSessionProtocol.loadRevisions(List<RevisionInfo>, CDOBranchPoint, int, int) line: 522 CDORevisionManagerImpl.loadRevisions(List<RevisionInfo>, CDOBranchPoint, int, int) line: 352 CDORevisionManagerImpl.getRevisions(List<CDOID>, CDOBranchPoint, int, int, boolean, SyntheticCDORevision[]) line: 263 CDORevisionManagerImpl.getRevision(CDOID, CDOBranchPoint, int, int, boolean, SyntheticCDORevision[]) line: 246 CDORevisionManagerImpl.getRevision(CDOID, CDOBranchPoint, int, int, boolean) line: 239 CDOTransactionImpl(CDOViewImpl).getRevision(CDOID, boolean) line: 317 CDOTransactionImpl(AbstractCDOView).createObject(CDOID) line: 749 CDOTransactionImpl(AbstractCDOView).getObject(CDOID, boolean) line: 668 CDOTransactionImpl.getObject(CDOID, boolean) line: 992 CDOTransactionImpl.getObject(CDOID, boolean) line: 1 CDOResourceImpl.getEObject(String) line: 596 MelodyValidatorAdapter(EObjectValidator).validate_UniqueID(EObject, DiagnosticChain, Map<Object,Object>) line: 1801 MelodyValidatorAdapter(EObjectValidator).validate_EveryDefaultConstraint(EObject, DiagnosticChain, Map<Object,Object>) line: 373 May be a bug in CDOResourceImpl.getEObject(String) related to ID attributes. I'm about to leave for Santa Clara and will not return before April. But I'll keep this issue in the queue.. Stéphane, can you attach a test case for our test framework, so that I can reproduce the problem? (In reply to comment #4) > Stéphane, can you attach a test case for our test framework, so that I can > reproduce the problem? It is really easy to reproduce the issue. Please use your own metamodel with an object that contains a string attribute set as an ID (from EMF point of view). Generate java API for this meta-model. Create a dummy model instance by code that instantiates many objects and set their id with generated string by java.util.UUID.randomUUID() (call the randomUUID at each set). Import this xmi model in a CDO repo (based on a DB store H2 for instance). From the editor opened by CDO as a result of the import operation, select the root model element, right click on it and run the standard EMF Validation action. This action reveals the bug. Committed revision 7632: - trunk/plugins/org.eclipse.emf.cdo.tests.model3 Committed revision 7633: - trunk/plugins/org.eclipse.emf.cdo.tests.model3 Committed revision 7632 Committed revision 7633 Committed revision 7634: - trunk/plugins/org.eclipse.emf.cdo.tests Created attachment 193777 [details]
Screenshot
Neither with the procedure you've described nor with org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_339908_Test I can reproduce this or a similar problem.
The first stack trace in the bug description implies that the server executes a normal LoadRevisionsRequest. That means, the client holds an object and is currently accessing one of the references of this object. The CDORevision of the object contains a CDOID for the target of the reference and the client can not find the adequate target revision in its cache. Hence it asks the server to load/provide this target revision by sending the target CDOID.
It appears that in your case this CDOID is an external ID, which is absolutely contradictory, because external IDs are resolved by the client's resourceset to something in a non-CDOResource.
The question is "why does your resourceset resolve this external ID to an object in your repo?" and I fear without a test case that reproduces this behaviour I can not answer it. Maybe you can ZIP up the relevant *executable projects* and send them to me privately?
(In reply to comment #10) > Created attachment 193777 [details] > Screenshot > > Neither with the procedure you've described nor with > org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_339908_Test I can reproduce this or > a similar problem. > > The first stack trace in the bug description implies that the server executes a > normal LoadRevisionsRequest. That means, the client holds an object and is > currently accessing one of the references of this object. The CDORevision of > the object contains a CDOID for the target of the reference and the client can > not find the adequate target revision in its cache. Hence it asks the server to > load/provide this target revision by sending the target CDOID. > > It appears that in your case this CDOID is an external ID, which is absolutely > contradictory, because external IDs are resolved by the client's resourceset to > something in a non-CDOResource. > > The question is "why does your resourceset resolve this external ID to an > object in your repo?" and I fear without a test case that reproduces this > behaviour I can not answer it. Maybe you can ZIP up the relevant *executable > projects* and send them to me privately? I will ask to do that for sure. (In reply to comment #10) > The question is "why does your resourceset resolve this external ID to an > object in your repo?" and I fear without a test case that reproduces this > behaviour I can not answer it. Eike, we're observing the problem here with our custom editors as well. The root cause seems to be EObjectValidator.validate_UniqueID(EObject, DiagnosticChain, Map<Object, Object>) and the way it deals with IDs. Essentially, validate_UniqueID does the following: String id = EcoreUtil.getID(eObject); Resource resource = eObject.eResource(); EObject otherEObject = resource.getEObject(id); That is, there's a hardcoded assumption that an object's unique ID can be directly used as an URI fragment. But if I remember correctly there's no such contract. In our case the unique ID is a base32 encoded UUID like 'EABCDEFGHIJKLMNOPQRSTUV123'. If one dares to call CDOResourceImpl.getEObject(String) with this ID as fragment, CDOIDUtil.read(String) internally inspects the 1st character to deceide what kind of OID to create. Unfortunately, that would be an external OID in this case. The resource's CDOView is then queried for an object with this OID and the error described by Stéphane appears. As a quick workaround, I simply disabled the whole validate_UniqueID check as I don't need it anyway. But I think a bug should be filed against EObjectValidator. Moving all open bug reports to 4.1 because the release is very near and it's hghly unlikely that there will be spare time to address 4.0 problems. Please make sure that your patches can be applied against the master branch and that your problem is not already fixed there!!! Moving all open issues to 4.2. Open bugs can be ported to 4.1 maintenance after they've been fixed in master. In the meantime we've got changes in CDOResourceImpl.getEObject(uriFragment) and we've got client-assigned CDOIDs (through a CDOIDGenerator in the CDOSession). Please reopen this bug if you feel a need. |