Issue 2772: Potential deadlock with POA::deactivate_object() Jira Issue CORBA31-1
Issue 3097: Custom Value Marshaling Issue Jira Issue CORBA31-2
Issue 3459: DynValue & custom valuetypes Jira Issue CORBA31-3
Issue 3674: Polymorphic Valuetypes and the DII Jira Issue CORBA31-4
Issue 3907: Issue: CSIv2 Identity Assertion Jira Issue CORBA31-5
Issue 4065: How does an ORB implement Object::get_policy for PI defined policies? Jira Issue CORBA31-6
Issue 4137: Implications of any/valuetype marshalling Jira Issue CORBA31-7
Issue 4169: Avoiding RSC/TSC copy on server side Jira Issue CORBA31-8
Issue 5214: Proposal for extension to CosNaming Jira Issue CORBA31-9
Issue 5231: New issue: ForwardRequest(<local object>) Jira Issue CORBA31-10
Issue 5266: ForwardRequest is impossible to detect in clients Jira Issue CORBA31-11
Issue 5439: processing TaggedComponents within an IOR Jira Issue CORBA31-12
Issue 5467: How does DynValue handle derived valuetypes? Jira Issue CORBA31-13
Issue 5621: messaging router issue Jira Issue CORBA31-14
Issue 5624: Spec doesn't make clear what is valid mix of policies and what is invalid Jira Issue CORBA31-15
Issue 5662: Messaging Routing Protocol is broken for GIOP 1.0 & 1.1 Jira Issue CORBA31-16
Issue 5781: What is the RSC when using a PersistentPoller Jira Issue CORBA31-17
Issue 5856: Bad text in 22.6 mandates Routing for sendc/sendp Jira Issue CORBA31-18
Issue 5880: Clarification on multi-threaded codeset negotiation Jira Issue CORBA31-19
Issue 5892: restriction of where a valuetype chunk can end Jira Issue CORBA31-20
Issue 5895: Problem with ServerRequestInterceptor::receive_request and DSI Jira Issue CORBA31-21
Issue 5899: rules for marshalling ValueBoxes Jira Issue CORBA31-22
Issue 5941: valuetype fragmentation ambiguous Jira Issue CORBA31-23
Issue 5952: BNF changes Jira Issue CORBA31-24
Issue 6007: Mapping from -ORBxxx to Java properties does not work for -ORBInitRef Jira Issue CORBA31-25
Issue 6050: 15.3.3 - codesets must be "explicitly defined" Jira Issue CORBA31-26
Issue 6283: CodeSet and CSIv2 Negotitaion Jira Issue CORBA31-27
Issue 6285: Change new GIOP Negotiate Session Message to Firewall Specific Jira Issue CORBA31-28
Issue 6287: Chapter/section: 15.4.2.2 "Request Body" Jira Issue CORBA31-29
Issue 6314: GIOP Conformance and Interceptors Jira Issue CORBA31-30
Issue 6318: valuetypes and local interfaces Jira Issue CORBA31-31
Issue 6391: Interface Introspection Jira Issue CORBA31-32
Issue 6424: Section 22.2.4.6 interface RelativeRoundtripTimeoutPolicy Jira Issue CORBA31-33
Issue 6899: CORBA 3.02, page 11-25, section 11.3.6 Jira Issue CORBA31-34
Issue 7340: module SendingContext Jira Issue CORBA31-35
Issue 7592: An extension of IOR to protect target objects Nature Jira Issue CORBA31-36
Issue 7730: Codec Interface Deficiencies Jira Issue CORBA31-37
Issue 7890: methods on the POA Jira Issue CORBA31-38
Issue 7892: Add a typedef for the POAManager id Jira Issue CORBA31-39
Issue 7893: change in the POAManager Jira Issue CORBA31-40
Issue 7896: argument of the set_servant call has a small typo Jira Issue CORBA31-41
Issue 7900: omission from the OMG --Trader spec Jira Issue CORBA31-42
Issue 7955: The POA state inactive is not used consistent. Jira Issue CORBA31-43
Issue 7978: CORBA 3.0.3 ch. 3.4 OMG IDL Grammar Jira Issue CORBA31-44
Issue 8221: Section: 4.3.13 Jira Issue CORBA31-45
Issue 8230: Appendix A Jira Issue CORBA31-46
Issue 8244: Code Set Conversion on Operations Jira Issue CORBA31-47
Issue 8586: Moving *Seq typedefs into ORB chapter Jira Issue CORBA31-48
Issue 8618: Minor code ambiguity Jira Issue CORBA31-49
Issue 8629: Typo in sections 22.10.1.1 and 22.10.1.2 Jira Issue CORBA31-50
Issue 8630: Section: 7.4 Jira Issue CORBA31-51
Issue 8631: Section: 13.6.2 Jira Issue CORBA31-52
Issue 8632: Section: 4.2 Jira Issue CORBA31-53
Issue 8633: Section: 4.2 (02) Jira Issue CORBA31-54
Issue 8783: update the spec to not used anonymous types Jira Issue CORBA31-55
Issue 8843: Section: 21.7 Jira Issue CORBA31-56
Issue 8844: Section: 21.9.1 Jira Issue CORBA31-57
Issue 8856: Section: 21.4.3.1 Jira Issue CORBA31-58
Issue 8860: Section: 4.5.2 Jira Issue CORBA31-59
Issue 8862: Section: 21.3.14.11 Jira Issue CORBA31-60
Issue 8864: Section: Appendix A Jira Issue CORBA31-61
Issue 8874: Page: 21-5 Jira Issue CORBA31-62
Issue 8879: Page: 9-1 Jira Issue CORBA31-63
Issue 8881: Page: 7-7 Jira Issue CORBA31-64
Issue 8929: NVList Section: 7.5 Jira Issue CORBA31-65
Issue 8969: Allowing Mutual Recursion for IDL Structures Jira Issue CORBA31-66
Issue 8985: Section: Chapter 11 Jira Issue CORBA31-67
Issue 8986: Section: Chapter 9, Chapter 5 Jira Issue CORBA31-68
Issue 9016: Section: 11.3.9 Jira Issue CORBA31-69
Issue 9075: Section: 22.16/ Jira Issue CORBA31-70
Issue 9082: Section: 22.11.1 Jira Issue CORBA31-71
Issue 9112: Page: 21-43 Jira Issue CORBA31-72
Issue 9118: Page: 56..64 Jira Issue CORBA31-73
Issue 9140: FullInterfaceDescription and base_interfaces question Jira Issue CORBA31-74
Issue 9460: Section: 11.3.9.16 Jira Issue CORBA31-75
Issue 9618: CORBA Exceptions Jira Issue CORBA31-76
Issue 10558: Allowing mutual recursion for IDL structs - clarification needed Jira Issue CORBA31-77
Issue 10817: Section: 21.3.13 Jira Issue CORBA31-78
Issue 11161: Section: 13.6.10.1 Jira Issue CORBA31-79
Issue 11332: Section: 15.4.2/16.4.1 Jira Issue CORBA31-80
Issue 11514: Proposal to change PortableInterceptor::ReplyStatus to a real enum Jira Issue CORBA31-81
Issue 11515: Proposal to change PortableInterceptor::AdapterState to a real enum Jira Issue CORBA31-82
Issue 11525: Third line of 23.1.3.4, ACTIVE must be bold Jira Issue CORBA31-83
Issue 12229: definition of Invalid Policies changed Jira Issue CORBA31-84
Issue 12230: mention of (deprecated) function get_implementation removed from text Jira Issue CORBA31-85
Issue 12376: Section: Part 2, Chapter 11 - MIOP Jira Issue CORBA31-86
Issue 12549: struct PolicyValue Jira Issue CORBA31-87
Issue 12550: move struct to IOP module Jira Issue CORBA31-88
Issue 12551: Section: 4.8.1 Jira Issue CORBA31-89
Issue 12555: Section: 21.7.3 Jira Issue CORBA31-90
Issue 12559: Section 13.7 ServiceContext Jira Issue CORBA31-91
Issue 12773: add CORBA::ORB::arg_list Jira Issue CORBA31-92
Issue 12857: add interface ORB { Object string_to_object ( in wstring str ); }; Jira Issue CORBA31-93
Issue 13056: 16.10 lists register_initial_reference Jira Issue CORBA31-94
Issue 13105: There is lack of multiplex publisher port that would mimic functionality of multiplex receptacle Jira Issue CORBA31-95
Issue 15713: missing document title Jira Issue CORBA31-96
Issue 15714: Bad quotes and imported dot Jira Issue CORBA31-97
Issue 15715: rule (85) is misplaced Jira Issue CORBA31-98
Issue 16047: Make anonymous types illegal Jira Issue CORBA31-99
Issue 16315: interface ORB should be local Jira Issue CORBA31-100
Issue 16887: Relationship connector and components/homes not clearly specified Jira Issue CORBA31-101
Issue 16942: Redundant bullet Jira Issue CORBA31-102
Issue 16996: context should be local interface Jira Issue CORBA31-103
Issue 17208: Add create_policy with just the type as argument Jira Issue CORBA31-104
Issue 17273: Two typo's in Annex A.4 Jira Issue CORBA31-105
Issue 18150: Invalid IDL Jira Issue CORBA31-106
Issue 18151: Invalid IDL (2) Jira Issue CORBA31-107
Issue 18152: Missing PolicyValue encoding instructions Jira Issue CORBA31-108
Issue 18153: Missing size information for decompress() Jira Issue CORBA31-109
Issue 2772: Potential deadlock with POA::deactivate_object() (corba-rtf)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: The draft CORBA 2.3 spec (ptc/99-03-07) does not deal with a potential deadlock situation. If an object is explicitly deactivated with POA::deactivate_object(), the object remains in the active object map until all operations pending on the object have completed. Any attempts to reactivate the object (implicitly via a ServantActivator, or explicitly via activate_object_with_id()) must block until the pending invocations have completed. However, if a servant's implementation of an object deactivates the object and then (directly or indirectly through a call to another collocated object) reactivates the object, the invocation will deadlock.
Resolution: Deferred to next RTF
Revised Text:
Actions taken:
June 28, 1999: received issue
April 11, 2012: Deferred
Discussion:
Issue 3097: Custom Value Marshaling Issue (corba-rtf)
Click here for this issue's archive.
Source: Camros Corporation (Mr. Jeffrey A. Marshall, jam(at)camros.com)
Nature: Uncategorized Issue
Severity:
Summary:
Due to the way that custom values are marshaled it is nearly impossible for a bridge (or other process) to process/forward GIOP messages which contain custom marshaled values (which the bridge has no compile/run-time knowledge of). The main issue is that the "alignment" of the custom marshaled data is unknown, other than the data will always start on a four byte boundry due to the presence of chunking. Should/could the value encoding format be changed to enforce eight byte alignment for all custom marshaled data (chunks)? This would allow bridges and other tools to process->[store]->forward messages containing custom values.
The CORBA 2.3.1 specification does not cover the interaction between the DynValue interface and custom valuetypes. I frankly don't see any way that the DynValue interface can possibly correctly handle a custom valuetype when the ORB does not have a factory for the type. It is theoretically possible for DynValue to properly work with a known custom type, but the implementation strategy could not be based on parsing the marshalled form of the valuetype. So, there are two issues that need to be addressed: 1. Should DynValue handle custom valuetypes at all? 2. For the set of custom valuetypes that it cannot handle, what exceptions should be raised by each operations?
Using the static invocation interfaces, it is possible to receive a valuetype that derives from the one declared in an operation, as long as a valuetype factory is known in the receiver (truncation is not the issue here). The same is not possible at the DII: When creating the request, the caller must indicate what type it expects, by forming a named value. Conceptually, the typecode in the named value should be the typecode of the base of all acceptable value types. However, if the ORB receives a derived type, it has no means of unmarshalling it - even if the application has knowledge about the derived type. What is missing is an interface to make typecodes of value types known to the ORB; with those, the ORB could then understand the CDR of the valuetype, and create a DynAny when asked to.
Issue on Document orbos/2000-08-04, CSIv2 Joint Submission Document: orbos/2000-08-04, CSIv2 Joint Submission Subject: Identity Assertion of X.501 Distinguished Name is not good enough Severity: Critical Summary: The Identity Token union contains a branch that is labled X501DistinguishedName. A single DN is insufficient to identify an entity. A path of X501Distinguished Names is needed instead. Also, other concerns about naming types are raised. Discussion: An X.501 Distinguished Name is insufficient to identify a single entity. The name must be accompanied by the name of its defining authority. In the case of public key certificates, the names certificate authority must be included. The chain of DNs in this manner must be included up to a root authority to have any definitive meaning. This approach will be consistent with the client sending a X.509 Certificate Chain. A DN path is actually defined by the certificate chain. Furthermore, the DN path should only come from an authority that is acceptable to the server, whether it be a DN path, or an X.509 Certificate Chain. The IOR should list the acceptable authorities and their name types. It is becoming more an more evident that we must invent GSS_NT_Export_Name types for X.509 Certificate Chain and X.501 DN path. The SAS_ContextSec structure should list, instead of the naming types, the naming authorities! We shall assume that the name types of the asserted identities shall be the same as the name types of listed naming authorities in the IOR. This is the only way this procedure can work Interoperable and without the client Guessing what it should do. Suggestions: An OID for an X.509 Public Key Certificate Chain shall be defined for a GSS Export Name, and its encoding will be a ASN1 sequence of and X.509 certificate with the least significant certificate first. An OID for an X.501 Distinguished Name Path shall be defined for a GSS Exported Name, and its encoding shall be an ASN1 sequence of an X.501 Distinguished Name with the least significant name first. To avoid having the target put a whole certificate chain in its IOR, a new OID shall be allocated in which its GSS Exported Name encoding is a X.501 DN path, but stipulates that the client should send a certificate chain from that named authority. This GSS Exported Name shall only be used in IORs and not for transmission in the Identity Token. typedef Security::GSS_NT_ExportedName NamingAuthority; struct CompoundSecMech { Security::AssociationOptions target_requires; IOP::TaggedComponent transport_mech; sequence<ServiceConfiguration> privilege_authorities; sequence<NamingAuthority> naming_authorities; };
The description for Object::get_policy (in the Core, section 4.3.7.1) states: "The get_policy operation returns the policy object of the specified type (see Policy Object on page 4-32), which applies to this object. It returns the effective Policy for the object reference. The effective Policy is the one that would be used if a request were made." For a policy defined by PI, I don't see anyway for the ORB to implement this operation correctly, since there isn't any way for it to know how to properly resolve any client override policies with the policy information stored in the IOR. When a invocation is actually in process, the ClientRequestInterceptor can use the information available in the ClientRequestInfo interface to get the client override and the IOR policy data and do the correct resolution before continuing with the request. However, Object::get_policy() needs to do the same type of thing, but it has no invocation context to do it in. I think the same problem also applies to the implementation of ClientRequestInfo::get_request_policy(). I think we need a new interception point to do this work. Something like: local interface PolicyInterceptor { any determine_effective_policy(in PolicyInfo pi); }; local interface PolicyInfo { readonly attribute Object target; readonly attribute Object effective_target; readonly attribute IOP::TaggedProfile effective_profile; IOR::TaggedComponent get_effective_component (in IOP::ComponentId id); IOP_N::TaggedComponentSeq get_effective_components (in IOP::ComponentId id); }; If this turns out to be an acceptable solution, then we should also change ClientRequestInfo to: local interface ClientRequestInfo : RequestInfo, PolicyInfo { ... }; and remove the redundant operations.
RE: CCM chapters document [orbrev] 99-10-04, section 61.6.2, page 61-45. The document citation indicates that the integrity of the valuetype -- that is, the received marshalled state -- is to be preserved in an ORB-mediated operation, even if that valuetype cannot be unmarshalled, either partially (truncated) or at all. If this value is then passed to another operation, the original marshalled state is to be transmitted. This preserves the transmitted object in its entirety, regardless of local implementation concerns. This is obviously necessary for bridges or event processing, such as through the notification service. So the question arises, what happens if you have a partial (truncated) unmarshall and the recipient application changes the local state of the valuetype through its attributes or local operations? How can/will you even know the state was changed? Do you ignore the changes and send the originally received marshalled stream, send only the new valuetype even though it is a truncation of the original, or "merge" the new values for the unmarshalled part followed by the original appended data for the truncated part? Should this third option be possible through an explicit ORB call -- that is, the application is responsible to identify the change in state to the ORB? I assume that the semantics of "truncatable" must come to include the understanding that data in the truncatable portions may not be contextually dependent on the inherited parent of the valuetype. As a further question, is there a reason why this semantic interpretation should not be extended to be a general requirement rather than only with respect to transmission of anys? My experience has found that passing anys tends to be expensive and is avoided where it can be. A more general interpretation permits transmission of a comprehensive data structure among intermediate agents that only use (unmarshall) the information they need.
The integrity of value types contained in anys is a requirement on the ORB core, and an appropriate paragraph should be added to the Value Type Semantics chapter. This requirement is not limited to Components. The paragraph in the Components specification that mentions this requirement should be removed. This issue should then be moved to the Core RTF.
During the interceptor FTF we changed the server-side threading requirements such that all server-side points run in the same thread as the ServantManager and servant except receive_request_service_contexts. We attempted to update 21.4.4.4 "Request Scope vs Thread Scope" accordingly but knew we screwed the picture and wording up. So we punted to the RTF. The main problem with the current wording is that is forces a copy of of TSC/RSC before the servant manager and then receive_request are called. This is necessary because 21.4.4.5 item 5 says: "The receive_request points may modify the RSC, but this no longer affects the TSC." The only way to make RSC identical to TSC in receive_request with respect to reading but also have them be independent with respect to writing is to make a copy (which could be optimized to copy-on-write, but why?). I suggest we just state they are equivalent after receive_request_service_contexts. Here is a proposed revision to ptc/00-08-06 along these lines. Comments? Harold 21.4.4.4 Request Scope vs Thread Scope ... On the server-side, the request scope PICurrent is attached to the ServerRequestInfo and follows the request processing. It is logically equivalent to the thread scope PICurrent after the list of receive_request_service_contexts interception points are processed. 21.4.4.5 Flow of PICurrent between Scopes 5. The ORB logically makes the RSC equivalent to the server-side TSC after the receive_request_service_contexts points are processed and before the servant manager is called. This TSC is within the context for both the receive_request points, the invocation of the servant manager, and the invocation of the target operation. The receive_request points are called. These points have access to the RSC. Modifying the RSC at this point makes corresponding modifications on the TSC. Since these points execute in the same thread as the target operation invocation, these points may modify the server-side TSC which makes corresponding modifications on the RSC. 6. After the receive_request points are called, control transfers to the server threads which may also read and write this server-side TSC. Any modifications to the TSC makes corresponding modifications on the RSC. 7. <No change> 8. <DELETE THIS ITEM> 9. The send interception points have access to the RSC (and the equivalent TSC) from which they may populate the reply service context list. After the invocation result is sent back to the client, the server-side RSC is logically destroyed. ... The picture would also need updating, but let's agree on wording first.
Since there doesn't appear to be a CosNaming mailing list this seems like as good a forum as any this discussion. It has long struck me that the use of CosNaming for JNDI in J2EE applications creates a significant outage in being able to bind and retrieve objects that are not remote (see the EJB 2.0 spec for details). In JNDI you can bind pretty much anything that is Remote (aka an Object reference) or Serializable (aka a valuetype), however CosNaming only allows you to do the former. One easy way to solve this would be to create a new NamingContext extension that allows one to bind and resolve Any's. This is in keeping with the Java-to-IDL spec's treatment of untyped Java objects and at the same time would not compromise non-java implementations. For JNDI it would only be necessary to support Any's containing: 1. Object references 2. valuetypes 3. valueboxes An exception could be thrown for any other types. The candidate interface might look something like this: module CosNaming { interface NamingContextAny : NamingContextExt { exception TypeNotSupported {}; void bind_any(in Name n, in any obj) raises (NotFound, CannotProceed, InvalidName, AlreadyBound, TypeNotSupported); void rebind_any(in Name n, in any obj) raises(NotFound, CannotProceed, InvalidName, TypeNotSupported); any resolve_any (in Name n) raises (NotFound, CannotProceed, InvalidName); any resolve_str_any(in StringName n) raises (NotFound, CannotProceed, InvalidName, AlreadyBound); }; }; The implementation of this interface in Java is trivial, although perhaps less so in other languages. Whether or not that matters is open to question.
The Portable Object Adapter and Portable Interceptors both are able to raise a ForwardRequest exception to allow redirection to another object. What happens if the ForwardRequest is to a local object? Is this even possible? Should it be allowed? I suggest we change the specification to make this illegal.
REQUIREMENT To be able to use interceptors, and in particular ForwardRequest, in a client to perform active, per-request, load-balancing. PROBLEM It is not possible to detect in an interceptor whether ForwardRequest has previously been thrown for the same client request. Thus it is possible for a client to go into an infinite loop throwing ForwardRequest. DISCUSSION The basic problem is that although for a single client request the request-scoped PICurrent is shared across across interceptor invocations - even when ForwardRequest is thrown - it is not possible to *modify* this information in an interceptor to indicate to a future invocation that the invocation has been seen. The two relevant parts of the spec here are: 21.3.6.5 For retries, depending on the policies in effect, a new request may or may not follow when a retry has been indicated. If a new request does follow, while this request is a new request, with respect to Interceptors, there is one point of correlation between the original request and the retry: because control has not returned to the client, the request scoped PortableInterceptor::Current for both the original request and the retrying request is the same (see Chapter 21, Portable Interceptors on page 21-32). 21.4.2 Before an invocation is made, PICurrent is obtained via a call to ORB::resolve_initial_references ("PICurrent") From within the interception points, the data on PICurrent that has moved from the thread scope to the request scope is available via the get_slot operation on the RequestInfo object. A PICurrent can still be obtained via resolve_initial_references, but that is the Interceptor's thread scope PICurrent. See section 21.4.4.4, Request Scope vs Thread Scope on page 21-36 for a detailed discussion of the scope of PICurrent. Thus modifications to the thread's PICurrent are lost on retries and modifications to the request's PICurrent are not possible. PROPOSED RESOLUTION I have made several different attempts at coming up with a portable way of solving this problem without changing the spec, but have failed. It seems to me that it really should be possible for the interceptor to know that a retry is in effect and I can think of a number of different solutions to this: 1. add: void set_slot (in SlotId id, in any data) raises (InvalidSlot); to RequestInfo. This would allow interceptors to transfer information between invokes of the same client request and thus a retry could be detected. 2. Add a new function to RequestInfo to indicate that a forward is in operation. The minimalist fix here would be to allow forward_reference() to be accessed in send_request() as well as in receive_other(). i.e. returning the object from the previous ForwardRequest if that has been thrown. I'm ambivalent about which of these is best but for the sake of simplicity I'm going to plump for (1) because this is already allowed in ServerRequestInfo. So: - Change the IDL in 21.3.12 to include void set_slot (in SlotId id, in any data) raises (InvalidSlot); - After 21.3.12.12 move in the text from 21.3.14.6 - Change the IDL in 21.3.14 to remove set_slot()
The overhead of processing TaggedComponents within an IOR becomes significant when done many times, as in the case of J2EE implementations where multiple interceptors are used. The definition of IORs in the IOP module is intended to support transmission and interoperability, rather than efficient access to the local, ORB specific, internal structure. I would like to propose that an abstract model of an IOR is introduced which recognises that many of the constituent parts of IOR profiles are identical for different objects, along the following lines:- - an IOR has a type ID string, and contains TaggedProfile instances - a TaggedProfile has an ID and data - an IIOPProfile is a TaggedProfile; it is composed of an IIOPProfileTemplate and an object ID. - an IIOPProfileTemplate has IIOP addressing information, and contains TaggedComponents. - a TaggedComponent has an ID and data - a TaggedComponentFactory creates a TaggedComponent - a TaggedProfileFactory creates a TaggedProfile with corresponding IDL definitions that allow the language bindings to optimise conversion between transmission and internal IOR formats to provide a performant and natural interface for IOR access. Rationale: In Java, for example, it should be possible to manipulate IOR TaggedProfiles and IIOPProfileTemplate TaggedComponents using the facilities of the Java collections framework, or at least some equivalent facility that is a natural Java idiom. Templates can be used to create IIOPProfiles because the basic object adapter model for object creation is to establish many of the properties of an IOR when the object adapter is created. - This has been present for the POA essentially from the beginning, since policies can only be passed to create_POA, and cannot be changed on an existing POA. - The Portable Interceptors work has also made this clear, since the IOR interceptor establish_components method, which is the only time that user code can add tagged components to an IOR, is only guaranteed to be called once for each distinct set of server policies i.e need only be run when an object adapter is created. - It is also likely that more than one object within an adapter will map to a TCP endpoint. TaggedProfile and TaggedComponent are intended as frameworks that may be extended to support application defined tagged profiles and components. To support this it is necessary to be able to register TaggedProfile and TaggedComponentFactory instances with an ORB, in which case any IOR unmarshalled by that ORB instance will use the registered factory to unmarshal the tagged profile or component. Since there has already been quite a bit of discussion about this in the Java RTF, here is a proposal for review:- Proposal: - add the following sections after the IOR Interceptor Overview:- 21.5.2 An Abstract Model for IORs To support efficient access to IORs, avoiding repeated marshaling and demarshaling of IOR components, it is helpful to have an abstract model of the, ORB specific, local representation of an IOR. Recognising that many of the constituent parts of IOR profiles are identical for different objects allows the following model to be defined:- - an IOR has a type ID string, and contains TaggedProfile instances - a TaggedProfile has an ID and data - an IIOPProfile is a TaggedProfile; it is composed of an IIOPProfileTemplate and an object ID. - an IIOPProfileTemplate has IIOP addressing information, and contains TaggedComponents. - a TaggedComponent has an ID and data - a TaggedComponentFactory creates a TaggedComponent - a TaggedProfileFactory creates a TaggedProfile 21.5.3 Local IOR Interfaces The following interfaces provide access to the data within a local IOR using this model. TaggedProfile and TaggedComponent are generic interfaces. Users of the ORB may create implementations of them. Corresponding factories may be registered with the IORFactory. The IORFactory is obtained through a call to ORB::resolve_initial_references ("IORFactory") and may also be used to obtain an IOR for an Object. An ORB must return all tagged profiles in an IOR through the IOR getProfiles operations. The ProfileIterator interface allows a client to iterate through the TaggedProfiles using the next operation. Those profiles whose ids have a registered TaggedProfileFactory will be made available in the form returned by the registered factory's TaggedProfileFactory create operation, which must return a subtype of TaggedProfile. An ORB will provide a TaggedProfileFactory implementation for the IIOPProfile. Profiles with ids for which no TaggedProfileFactory has been registered will be made available as instances of a generic ORB implementation of TaggedProfile. Similarly, an ORB must return all tagged components in an IIOP profile through the IIOPProfile().getTemplate().getComponents() operations. The ComponentIterator interface allows a client to iterate through the TaggedComponents using the next operation. Those components whose ids have a registered TaggedComponentFactory will be made available in the form returned by the registered factory's TaggedComponentFactory create operation, which must return a subtype of TaggedComponent. Components with ids for which no TaggedComponentFactory has been registered will be made available as instances of a generic ORB implementation of TaggedComponent. module PortableInterceptor { local interface TaggedComponent { readonly attribute IOP::ComponentId component_id; readonly attribute CORBA::OctetSeq component_data; IOP::TaggedComponent convert(); }; local interface ComponentIterator { TaggedComponent next(); boolean has_next(); }; local interface TaggedProfile { readonly attribute IOP::ProfileId profile_id; readonly attribute CORBA::OctetSeq profile_data; IOP::TaggedProfile convert(); }; local interface ProfileIterator { TaggedProfile next(); boolean has_next(); }; local interface IOR { readonly attribute string type_id; ProfileIterator get_profiles (); ProfileIterator get_profiles_by_id (in IOP::ProfileId profile_id); }; local interface IIOPProfileTemplate { readonly attribute IIOP::Version iiop_version; readonly attribute string host; readonly attribute unsigned short port; ComponentIterator get_components(); ComponentIterator get_components_by_id (in IOP::ComponentId id); }; local interface IIOPProfile:TaggedProfile { readonly attribute CORBA::OctetSeq object_key; readonly attribute IIOPProfileTemplate profile_template; }; local interface TaggedComponentFactory { readonly attribute IOP::ComponentId factory_id; TaggedComponent create_tagged_component (in CORBA::OctetSeq component_data); }; local interface TaggedProfileFactory { readonly attribute IOP::ProfileId factory_id; TaggedProfile create_tagged_profile (in CORBA::OctetSeq profile_data); }; local interface IORFactory { IOR create_ior (in Object obj); void register_tagged_profile_factory (in TaggedProfileFactory tpf); void register_tagged_component_factory (in TaggedComponentFactory tcf); }; }; 21.5.3.1 IOR Factory Interface create_ior Return an IOR relating to the given Object. If create_ior is invoked when the object reference is not bound, standard system exception BAD_INV_ORDER with minor code n will be raised. register_tagged_profile_factory Register a TaggedProfileFactory to create TaggedProfiles with the id returned by the given factory's getId method. If a TaggedProfileFactory already exists for the given id, standard system exception BAD_INV_ORDER is raised with a standard minor code of n+1. Instances of this interface may be defined by users to support custom tagged profiles. register_tagged_component_factory Register a TaggedComponentFactory to read TaggedComponents with the id returned by the given factory's getId method. If a TaggedComponentFactory already exists for the given id, standard system exception BAD_INV_ORDER is raised with a standard minor code of n+2. Instances of this interface may be defined by users to support custom tagged components. 21.5.3.2 IOR Interface This interface gives access to a local representation of an IOP::IOR. type_id The type id string from the IOR. get_profiles Returns an iterator over the TaggedProfiles within the IOR. get_profiles_by_id Returns an iterator over the TaggedProfiles with the given Profileid. 21.5.3.3 TaggedProfile Interface This interface gives access to a local representation of an IOP::TaggedProfile. profile_id This attribute is the identifier for this TaggedProfile. profile_data This attribute is the data from the TaggedProfile. It is normally a CDR encapsulation. convert Create an IOP representation of this TaggedProfile 21.5.3.4 TaggedComponent Interface This interface gives access to a local representation of an IOP::TaggedComponent. component_id This attribute is the identifier for this TaggedComponent. component_data This attribute is the data from the TaggedComponent. It is normally a CDR encapsulation. convert Create an IOP representation of this TaggedComponent. 21.5.3.5 TaggedProfileFactory Interface factory_id This attribute is the identifier of profiles created by this TaggedProfileFactory. create Create a TaggedProfile from the given profile_data. 21.5.3.6 TaggedComponentFactory Interface factory_id This attribute is the identifier of components created by this TaggedComponentFactory. create Create a TaggedComponent from the given component_data. 21.5.3.7 ProfileIterator Interface next Returns the next TaggedProfile in the iteration. If next is called after the last TaggedProfile has been returned, BAD_INV_ORDER will be raised with a standard minor code of n+3. If an IOR is modified in between calls to next, the behavior of further calls to next is implementation dependent. has_next Returns true if the iteration has more elements. In other words, returns true if next would return an element rather than throwing an exception. 21.5.3.8 ComponentIterator Interface next Returns the next TaggedComponent in the iteration. If next is called after the last TaggedComponent has been returned, BAD_INV_ORDER will be raised with a standard minor code of n+3. If a profile is modified in between calls to next, the behavior of further calls to next is implementation dependent. has_next Returns true if the iteration has more elements. In other words, returns true if next would return an element rather than throwing an exception. 21.5.3.9 IIOPProfile Interface object_key This attribute is the Object key contained in this IIOPProfile. profile_template This attribute is the IIOPProfileTemplate associated with this IIOPProfile. 21.5.3.10 IIOPProfileTemplate Interface iiop_version This attribute is the GIOP version of this profile. If the major value is 1 and the minor value is 0, this profile cannot contain any TaggedComponents. host This attribute is the host name string of this IIOPProfileTemplate. port This attribute is the port number of this IIOPProfileTemplate. get_components Return an iterator over the TaggedComponents within the IIOPProfileTemplate. get_components_by_id Returns an iterator over the TaggedComponents with the given ComponentId. In current Section 21.5.3: - add the following after the ORBInfo Interface local interface IORInfo_3_n:IORInfo { ProfileIterator get_profiles (); ProfileIterator get_profiles_by_id (in IOP::ProfileId profile_id); }; - add the following sections: 21.5.3.4 get_profiles Returns an iterator over the TaggedProfiles within the IOR. 21.5.3.5 get_profiles_by_id Returns an iterator over the TaggedProfiles within the IOR with the given Profileid. Parameter Description profile_id The IOP::ProfileId of the profiles in the iteration to be returned. - add the IORFactory to the list of reserved ObjectIds for resolve_initial_references in section 4.5.2
I just noticed that the description of DynValue is totally silent on the issue of derived valuetypes. Here's an example to set things up: // IDL valuetype A { public short s; }; valuetype B { public long l; }; struct S { A an_a; }; // C++ DynamicAny::DynFactory df = ...; B *b = ...; S my_s; CORBA::Any my_any; s.an_a = b; my_any <<= s; DynamicAny::DynAny_var da = df->create_dyn_any(my_any); DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(da); ds->seek(0); da = ds->current_component(); DynamicAny::DynValue_var dv = DynamicAny::DynValue::_narrow(da); CORBA::TypeCode_var tc = dv->type(); cout << tc->id() << endl; ----------- Now some questions: 1. What is printed by the above C++ code? "IDL:A:1.0" or "IDL:B:1.0"? 2. If the typecode is for valuetype A, what happens to the members defined in valuetype B? Seems they must be inaccessable yet still recoverable if I convert the DynValue back to an any and extract the value, because I can't truncate a B to an A. 3. If the typecode is for valuetype B, we now have the interesting case where: tc->equivalent(ds->type()->member_type(0)) is false. Is this going to confuse programmers or programs? I think it will, since it means that if I try to insert dv into another DynStruct via assign() or the like, it will fail, since the TypeCodes are no longer equivalent. 4. Do the answers change if B is truncatable and the program can find the TypeCode for B (perhaps via SendingContextRunTime)? How about if it can't find the TypeCode?
What is a messaging router supposed to do if it receives multiple requests from a client with more than one type of QueueOrderingPolicy value? (Is this legal? Is it legal to have more than one QueueOrdering bit set in a single request?) How can it sort on priority, FIFO, and deadline simultaneously?
The spec doesn't make it clear what is a valid mix of policies and what is invalid. For example, should it be legal to set a RequestPriorityPolicy, MaxHopsPolicy or QueueOrderingPolicy value if the RoutingPolicy is ROUTE_NONE? Also, should setting both RequestEndTimePolicy and RelativeRequestTimeoutPolicy be illegal? Or must the client/server pick which ever one expires first?
It is impossible to use the routing protocol to communicate with servers that only support GIOP 1.0 or 1.1, because the information contained in struct MessageBody does not contain enough information to determine the alignment requirements of the contents of body member. The GIOP 1.0 & 1.1 RequestHeader struct contain an octet sequence for principle as the last member, and specify no alignment requirements for the message body. Thus, it is impossible for the final router to determine the proper alignment for the message body when marshalling a GIOP Request message for delivery to the target object. The same problem applies to the Response message.
What is the RSC when > using a PersistentPoller? Since it is a valuetype that can be passed > from one process to another, the RSC obviously can't be the same in the > other process as at the original invocation point. > > Anybody have any bright ideas for this one? Should it be empty? A copy > of the TSC at the poll point? Change MessageRouting:PersistentRequest > to have an attribute that provides access to a copy of the RSC, and > PersistentRequestRouter::create_persistent_request to have the RSC as an > "in" argument?
There is a sentence in the first paragraph of 22.6 that should be fixed: "The implementation of these methods must generate a method invocation as described in Section 22.14, Message Routing, on page 22-50." However, 22.2.5.3 allows asynchronous invocations to be delivered via synchronous protocols if the RoutingPolicy is ROUTE_NONE. This sentence should be changed to: "The implementation of these methods may generate a method invocation as described in Section 22.14, Message Routing, on page 22-50, depending on the effective RoutingPolicy for the invocation."
We recently ran into a problem with a foreign Vendor's ORB and it appears the spec is unclear on this issue. The problem occurs when a multi-threaded client is connecting to a server. The spec says (13.10.2.6): "Codeset negotiation is not performed on a per-request basis, but only when a client initially connects to a server. All text data communicated on a connection are encoded as defined by the TCSs selected when the connection is established." but is silent on what is supposed to happen if the client has multiple threads all trying to connect at the same time. The issue is that priority inversion can occur - either because the client sends out a request without the negotiated codeset before the one with the negotiated codeset, or because the server processes the request without the negotiated codeset before the one with the negotiated codeset (even if the latter was sent first). The problem we encountered was the latter. There are two possible approaches to solving this: a) Require the server to serialize connection establishment requests until the codeset (and other connection information) is negotiated. This requires that the client impose appropriate ordering on connection requests. b) Require that the client keep sending codeset (and other connection information) until it is sure that the server has received the information (by getting a reply back). This works ok unless you are exclusively using oneways. In this instance you have to keep sending codeset information forever (somewhat costly, and very costly for codebase information). CSIv2 (26.2.2.3) explicitly calls out (b) but I prefer (a). Do we have any guidance on what is supposed to happen?
There is a small issue with the restriction of where a valuetype chunk can end. The spec says "The data may be split into multiple chunks at arbitrary points except within primitive CDR types, arrays of primitive types, strings, and wstrings, or between the tag and offset of indirections. It is never necessary to end a chunk within one of these types as the length of these types is known before starting to marshal them so they can be added to the length of the currently open chunk." However, in the case of array of wchar, the length is not known before starting to marshal, since each char (in GIOP 1.2 and 1.3) is marshalled as a (sort-of) sequence of octets. I think it should be legal to end a valuetype chunk in the middle of an array of char.
21.3.9.2 states: "In the DSI model, since the parameters are first available when the user code calls arguments, receive_request is called from within arguments. It is possible that arguments is not called in the DSI model. The target may call set_exception before calling arguments. The ORB shall guarantee that receive_request is called once, either through arguments or through set_exception." The problem here, is that the DSI servant has already been invoked at this point, and the DSI implementation will be unaware that the server interceptor may have cancelled the invocation via raising a system exception or ForwardRequest user exception. So the DSI implementation will carry on, creating all sorts of wonderful havoc as it continues to interact with the ServerRequest PO. Any vendors want to comment on what their PI implementation does now? Proposed fix: First, we should define a new system exception minor code that the servant implementation can detect so that it can clean up and get out of the way as expeditiously as possible when raised by arguments or set_exception. Perhaps a minor code for OBJ_ADAPTER? Should there be two minor codes, to distinguish a system exception from ForwardRequest as the reason for cancelling the invocation? Second, we need some more text either in chapter 8 or 21 that states that any calls by the DSI implementation to ServerRequest::set_result or ServerRequest::set_exception will be ignored (or perhaps reraise the exception defined in the previous paragraph) if ServerRequestInterceptor::receive_request raises an exception.
The GIOP specification does not say anything at all about the rules for marshalling ValueBoxes. I believe the expected format is to marshal ValueBoxes as if they were a normal Value with a single member, and that they follow the normal rules about indirections and chunking. The spec should clearly state this.
Although I now think I know the intent of the spec, its is ambiguous if not plain wrong with respect to valuetype fragmentation. In particular 15.3.4.6: Bullet 1 says: "End tags, chunk size tags, and value tags are encoded using non-overlapping ranges so that the unmarshaling code can tell after reading each chunk whether: � another chunk follows (positive tag). � one or multiple value types are ending at a given point in the stream (negative tag). � a nested value follows (special large positive tag)." Bullet 3 says: "� For the purposes of chunking, values encoded as indirections or null are treated as non-value data." And the pseudo-BNF says: "(1) <value> ::= <value_tag> [ <codebase_URL> ] [ <type_info> ] <state> | <value_ref> (2) <value_ref> ::= <indirection_tag> <indirection> | <null_tag> (3) <value_tag> ::= long// 0x7fffff00 <= value_tag <= 0x7fffffff (4) <type_info> ::= <rep_ids> | <repository_id> (5) <state> ::= <octets> |<value_data>* [ <end_tag> ] (6) <value_data> ::= <value_chunk> | <value>" Now clearly the implication of bullet 1 is that an indirection or null must appear inside a chunk in a chunked encoding, otherwise you would be able to see the value 0 or -1 after a chunk and the -1 in particular could mean an end tag or an indirection. However the possible implication of bullet 3 and the BNF (note the use of "value data") is that nulls and indirections are values and thus must appear outside of chunks. Clearly the former interpretation is the correct one otherwise anarchy ensues. So I propose that we change the 3rd bullet to say: "For the purposes of chunking, values encoded as indirections or null are treated as if they were not values and therefore must always appear inside a chunk when a chunked encoding is in effect." and then change the BNF to say: "(1) <value> ::= <concrete_value> | <value_ref> (2) <concrete_value> ::= <value_tag> [ <codebase_URL> ] [ <type_info> ] <state> (3) <value_ref> ::= <indirection_tag> <indirection> | <null_tag> (4) <value_tag> ::= long// 0x7fffff00 <= value_tag <= 0x7fffffff (5) <type_info> ::= <rep_ids> | <repository_id> (6) <state> ::= <octets> |<value_data>* [ <end_tag> ] (7) <value_data> ::= <value_chunk> | <concrete_value>" etc
BTW I think the twiddle is incomplete because it is not reflected in the BNF for Identifier. I think it is better if the BNF always reflects the ultimate specification of a language's lexical definition. Otherwise compiler writers are apt to miss the subtleties. I'll propose some BNF changes if others agree
The CORBA 3.0 spec adds the following note in Section 4.5.1: ORB Initialization. "Whenever an ORB_init argument of the form -ORBxxx is specified, it is understood that the argument may be represented in different ways in different languages. For example, in Java -ORBxxx is equivalent to a property named org.omg.CORBA.ORBxxx." The approach stated in the above note does not work for -ORBInitRef. For example, if you have -ORBInitRef NameService=URL, you cannot translate the above arguments into a property named "org.omg.CORBA.ORBInitRef" because there can be only one property of this name and there may be many different services. This issue was slightly cover by Issue 3643 (java-rtf), which was not resolved. This issue becomes obvious and important because the note added in the CORBA 3.0 spec. Proposed solution: Arguments like "-ORBInitRef id=url" should be equivalent to a property named "org.omg.CORBA.ORBInitRef.id" with value "url".
For codesets in encapsulations we have: 15.3.3 - codesets must be "explicitly defined" Issue 4824 - "it is an error for a Service Context to depend on information that is not contained within the encapsulation to determine the codeset used within it" But in 13.8 there is no prescribed way of "explicitly defining" the codeset. Please, please can we simply define that the fallbacks in 13.10.2.6 apply everywhere that the codeset is not known (whether negotiated or not) and be done with it. Another alternative would be to add codeset parameters to the encode() and decode() functions of 13.8.
I believe that we send CSIv2 stuff in a GIOP Request until a corresponding GIOP reply has been containing corresponding CSIv2 context ids is sent. For Codeset, I think the policy is to send the service context in each GIOP request until a corresponding GIOP Reply is received, thereby saying that the "negotiation" is completed and excepted (otherwise an exception will be raised. We should probably look at the fact that multiple NSReq messages can be sent, and there are no corresponding reply messages depending on the service contexts. I think that these messages should be intercepted since they are delivering service contexts.
Here is a small proposal for GIOP 1.4 with Firewall and Bidirectional. We would get rid of all the weird nasty service contexts and make it simplistic. The FireWall messages are only allowed before any other GIOP messages. BiDir messages can happen at any time according to their protocol. What do you think? Asside from some problems I see with BiDir offer/challenge/response correlation, it is essentially equivalent to the solution proposed in the adopted spec. module GIOP { enum MsgType_1_4{ Request, Reply, CancelRequest, LocateRequest, LocateReply, CloseConnection, MessageError, Fragment, // GIOP 1.1 addition // GIOP 1.4 additions FirewallPathRequest, // 8 FirewallPathRepsonse, // 9 BiDirOffer, // 10 BiDirChallenge, // 11 BiDirResponse // 12 }; // Firewall Traversal GIOP 1.4 struct FirewallSpec { boolean is_intelligent; IOP::TaggedComponentSeq endpoints; }; typedef sequence<FirewallSpec> FirewallPath; struct FirewallPathRequestHeader { unsigned long host_index; FirewallPath path; }; // No body follows. enum FirewallPathResponseStatusType { NO_EXCEPTION, SYSTEM_EXCEPTION }; struct FirewallPathResponseHeader{ FirewallPathResponseStatusType status; boolean connection_complete; }; // Marshalled body immediately follows // Bidirectional GIOP 1.4 // To keep this file uncomplicated we can introduce the // headers and put the marshalled bodies in a separate BiDir module // Due due some issue about the challege/response protocol for this, // there may be a need of an offer_id to correlate them. struct BiDirOfferHeader{ unsigned long offer_id; }; // Marshalled body immediately follows. struct BiDirChallengeHeader { unsigned long offer_id; }; // Marshalled body immediately follows. struct BiDirResponseHeader { unsigned long offer_id; }; // Marshalled body immediately follows. };
Suppose you are sending a request (GIOP 1.2 or 1.3) and the request will be fragmented into two segments. The first segment is a Request message that has the GIOP Header and part of the Request Header. The second segment is a Fragment message that has a GIOP Header, a Fragment Header, and the body is the remainder of the Request Header and the Request Body. Section 15.4.2.2 of CORBA 3.0 states that the Request Body (in a Request Message) should always be aligned on an 8 octet boundary. My question is, in the above scenario, where the Request Body begins in the Fragment message, should the Request Body be aligned on an 8 octet boundary or not? I have not found anything in the specification that explicitly says what to do.
GIOP Conformance and Interceptor don't play well together. GIOP minor version conformance mandates two things. 1. That standard service contexts that are considered optional can be ignored should the implementation not understand them. 2. That certain service contexts get processed according to the specification of where they are defined. This requirement works well for GIOP 1.2 where a lot of them are optional, since (1) will apply. An implementation can claim 1.2 conformance and not process any of them. However, 1.3 and upcoming 1.4 will mandate the processing of them according to their specification. In many cases, this means that some default response may be required, which means that a GIOP 1.3, or later engine must have a "default" response for these service contexts. In an ORB that uses interceptors and has a generic GIOP messaging engine there is no way for the engine to "know" when or not to process a particular service context. It requires strict processing by the GIOP engine, or it requires "default" interceptors to be installed to maintain the level of conformance. However, interceptors have no way of "declaring" which service contexts they handle, and whether they they are overriding already installed (default) interceptors for processing those particular service contexts. For example, an non-transactional ORB that is GIOP 1.2 compliant must process the Transaction Service Context by raising a TRANSACTION_UNAVAILABLE exception, because by default the ORB is in the OTS_NOT_CONNECTED state. It cannot be ignored to comply with GIOP 1.2 (but by certain in implementations it ALWAYS is). A default interceptor is needed in the ORB implementation to do this. However, for an ORB configuration that wants to process this, there is no way for an interceptor to "override" default processing.
The spec appears silent as to whether valuetypes are allowed to support local interfaces. Table 3-10, for example, says nothing at all about local interfaces. There's a couple ways to look at this. First, valuetypes are not CORBA objects. Servants for local interfaces are direct CORBA object instances, i.e., the "local" declaration on an interface effectively removes the distinction between a CORBA object and its servant. If a valuetype were used as a servant for a local object, then the valuetype would itself also be a CORBA object. By this analysis, valuetypes should not be allowed to support local interfaces. Another way to look at it is that the valuetype should just inherit the local interface's operations and attributes without having any subtype/subclass relationship with the base local interface. This would be a rather pointless approach to take, is there would be no possibility of using the valuetype polymorphically with respect to the base local interface.
Inspired by a recent paper by Doug Schmidt and Steve Vinoski and the resulting newsgroup discussion on comp.object.corba, I have a feature request to introduce a better reflection mechanism into CORBA. At the moment, there is the CORBA::Object::get_interface() operation to access a matching InterfaceDef entry in an Interface Repository. Since an Interface Repository is seldomly deployed, using this operation is pretty much futile and will either return a nil reference or throw an exception. Therefore, I propose to add a new get_interface_def() operation to the Object interface that returns a FullInter- faceDef structure, as defined by the Interface Repository. This structure contains all that a dynamic client (such as the ones proposed by Schmidt&Vinoski, or software like CorbaScript or Combat) needs to know about an interface. A new _interface_def pseudo-operation then needs to be added to GIOP. This could probably be done without a version change, as no marshalling changes or new messages are involved, it's just another operation. On the server side, the IDL compiler would generate a suitable implementation as part of the skeleton. This implementation could just contain a binary representation of the FullInterface- Description structure (just like a "precompiled" TypeCode) that is dumped to the GIOP stream. (So that you don't need the Interface Repository IDL around.) Proposed resolution: In chapter 4.3, "Object Reference Operations," add the following operation to the Object interface: module CORBA { interface Object { // PIDL ... other operations ... FullInterfaceDescription get_interface_def (); }; }; Add the following explanation to 4.3.1, "Determining the Object Interface" 4.3.1.2 get_interface_def FullInterfaceDescription get_interface_def (); The get_interface_def operation returns a data structure describing the most derived type of the object addressed by the reference. The FullInterfaceDescription structure includes descriptions of all the operations and attributes in the transitive closure of the inheritance graph of the interface being described. See the Interface Repository chapter for the contents of the data structure. Note that if an Interface Repository is not available, object references contained in this structure may be nil or inaccessible. In chapter 15.4.2, "Request Message", update the text that reads In the case of CORBA::Object operations that are defined in the CORBA Core (Section 4.2, "Object Reference Operations," on page 4-12) and that correspond to GIOP request messages, the operation names are _interface, _is_a, _non_existent, _domain_managers and _component. to read In the case of CORBA::Object operations that are defined in the CORBA Core (Section 4.2, "Object Reference Operations," on page 4-12) and that correspond to GIOP request messages, the operation names are _interface, _is_a, _non_existent, _domain_managers, _component or _interface_def. In the C++ language mapping, section 1.37.1, "Mapping of PortableServer::Servant", add the following operation to class ServantBase: namespace PortableServer { // C++ class ServantBase { ... other operations ... virtual CORBA::FullInterfaceDescription_ptr _get_interface_def (); }; } Update the paragraph that reads, ServantBase provides default implementations of the _get_interface, _is_a and _non_existent object reference operations [...] to read ServantBase provides default implementations of the _get_interface, _is_a, _non_existent and _get_interface_def object reference operations [...] Add a new paragraph, For static skeletons, the default implementation of the _get_interface_def function returns information about the interface associated with the skeleton class. For dynamic skeletons, the default implementation uses the _get_interface function to determine its return value. Other language mappings might need similar updates. By the way, since FullInterfaceDescription is only used as a return value, only a pointer to FullInterfaceDescription is needed. Therefore, you don't need the full Interface Repository interface descriptions but only a pointer to an incomplete type. On the client side, you only need to pull in the Interface Repository IDL if you are actually calling _get_interface_def. On the server side, the skeleton can do some ORB-dependent magic to push a precompiled binary data structure into the result.
[..] It is used to indicate the relative amount of time for which a Request or its corresponding Reply may be delivered. After this amount of time, the Request is cancelled (if a response has not yet been received from the target) or the Reply is discarded (if the Request had already been delivered and a Reply returned from the target) [..] --------------------------------------------------------- Question: * What is the precise meaning of "Request is cancelled"? Does it mean that client ORB just gives up or does it mean that client tries, in kind of best effort semantics, to cancel request on server? If this cancellation fails, how will client user be informed about this? By a minor code in thrown Timeout exception? Is it possible to clarify this?
Fifth bullet near the beginning of this section states: Incarnations of a particular object may not overlap; that is, incarnate shall not be invoked with a particular ObjectId while, within the same POA, that ObjectId is in use as the ObjectId of an activated object or as the argument of a call to incarnate or etherealize that has not completed. Unfortunately, I do not see anywhere where the exception to be thrown from activate_object_with_id() for this case is specified. According to this text, if incarnate() is executing for a particular ObjectId, any calls to activate_object_with_id() should be rejected by the POA. This came up in comp.object.corba, where someone posted a question as to why Orbix 2000 throws the ObjectAlreadyActive exception for this case.
The CORBA specification has module SendingContext { //... interface CodeBase { //... CORBA::FullValueDescription meta(in CORBA::RepositoryId x); //... }; //... }; but there is no CORBA::FullValueDescription defined in the specification, yet the supplied <SendingContext.idl> file declares module SendingContext { //... interface CodeBase { //... CORBA::ValueDef::FullValueDescription meta(in CORBA::RepositoryId x); //... }; //... };
Related Specification: CommonObject Request Broker Architecture: Core Specification November 2002 Version 3.0 - Editorial edit to cover formal/02-11-03 Nature: Revision Subject: An extension of IOR to protect target objects Nature: Enhancement Issue Summary: IOR (Interoperable Object Reference) is the distributed reference of a CORBA object. The IOR of a target object is distributed to client applications that want to access the target object. Clients can easily connect to the target objects based on the location information in IOR. As a kind of object discovery scheme, IOR publishes some attributes related to target object, such as IP address, port number, internal object id, etc. As we know, many kinds of attacks can be performed to a target server when the IP address and port number of the target is exposed. The exposition of internal object id may also leads to security problems. We use Abstract IOR (AIOR) to make the originate IOR (we call it regular IOR) transparent to client applications, thus the target objects is protected from potential attacks. Proposed solution: We use proxy technology to protect target servers, following is the architecture of a typical scenario. Service Proxy (SP) acts as a portal for all background servers. SP will handle all requests from clients to background servers. So background servers are transparent to clients. +-------------+ +-------------+ | Client | Abstract IORs | Service | | application +-----------------++ Proxy | | | | | +-------------+ +---+--+--+---+ BS1's IORs | | | +---------------------------+ | | | BS2's IORs | | + +--------------+ | +------+-----+ + +-+ BS3's IORs | Background | +------+-----+ + | Server 1 | | Background | +------+-----+ +------------+ | Server 2 | | Background | +------------+ | Server 2 | +------------+ The core concept of the above architecture is Abstract IOR (AIOR). AIOR can be described by a simple equation: AIOR = SP's regular IOR + logical name Logical name is uniquely corresponding to an IOR of an object running on background server. So the SP should set up the mapping before corresponding request comes, and map the logical name in the AIOR to the regular IOR of the target object at background server for a coming request. The structure of AIOR is compatible to regular IOR. Firstly let's have a look at the structure of regular IOR defined at page 13-15. Then we will discuss how to support AIOR based on existing IOR data structures and what interfaces and methods will be defined. module IOP { // IDL // Standard Protocol Profile tag values typedef unsigned long ProfileId; struct TaggedProfile { ProfileId tag; sequence <octet> profile_data; }; typedef sequence <TaggedProfile> TaggedProfileSeq ; // an Interoperable Object Reference is a sequence of // object-specific protocol profiles, plus a type ID. struct IOR { string type_id; sequence <TaggedProfile> profiles; }; // Standard way of representing multicomponent profiles. // This would be encapsulated in a TaggedProfile. typedef unsigned long ComponentId; struct TaggedComponent { ComponentId tag; sequence <octet> component_data; }; typedef sequence<TaggedComponent> TaggedComponentSeq; }; CORBA specification defines 3 standard IOR profiles (at page 13-17): module IOP { const ProfileId TAG_INTERNET_IOP = 0; const ProfileId TAG_MULTIPLE_COMPONENTS = 1; const ProfileId TAG_SCCP_IOP = 2; typedef sequence <TaggedComponent> MultipleComponentProfile; }; The following are standard IOR components that can be included in TAG_INTERNET_IOP and TAG_MULTIPLE_COMPONENTS profiles, and may apply to IIOP, other GIOPs, ESIOPs, or other protocols. An ORB must not drop these components from an existing IOR (at page 13-19). module IOP { const ComponentId TAG_ORB_TYPE = 0; const ComponentId TAG_CODE_SETS = 1; const ComponentId TAG_POLICIES = 2; const ComponentId TAG_ALTERNATE_IIOP_ADDRESS = 3; const ComponentId TAG_ASSOCIATION_OPTIONS = 13; const ComponentId TAG_SEC_NAME = 14; const ComponentId TAG_SPKM_1_SEC_MECH = 15; const ComponentId TAG_SPKM_2_SEC_MECH = 16; const ComponentId TAG_KerberosV5_SEC_MECH = 17; const ComponentId TAG_CSI_ECMA_Secret_SEC_MECH = 18; const ComponentId TAG_CSI_ECMA_Hybrid_SEC_MECH = 19; const ComponentId TAG_SSL_SEC_TRANS = 20; const ComponentId TAG_CSI_ECMA_Public_SEC_MECH = 21; const ComponentId TAG_ GENERIC_SEC_MECH = 22; const ComponentId TAG_FIREWALL_TRANS = 23; const ComponentId TAG_SCCP_CONTACT_INFO = 24; const ComponentId TAG_JAVA_CODEBASE = 25; const ComponentId TAG_TRANSACTION_POLICY = 26; const ComponentId TAG_MESSAGE_ROUTERS = 30; const ComponentId TAG_OTS_POLICY = 31; const ComponentId TAG_INV_POLICY = 32; const ComponentId TAG_CSI_SEC_MECH_LIST = 33; const ComponentId TAG_NULL_TAG = 34; const ComponentId TAG_SECIOP_SEC_TRANS = 35; const ComponentId TAG_TLS_SEC_TRANS = 36; const ComponentId TAG_ACTIVITY_POLICY = 37; const ComponentId TAG_INET_SEC_TRANS = 123; }; The following additional components that can be used by other protocols are specified in the DCE ESIOP chapter of this document and CORBAServices, Security Service, in the Security Service for DCE ESIOP section (at page 13-19, 13-20): const ComponentId TAG_COMPLETE_OBJECT_KEY = 5; const ComponentId TAG_ENDPOINT_ID_POSITION = 6; const ComponentId TAG_LOCATION_POLICY = 12; const ComponentId TAG_DCE_STRING_BINDING = 100; const ComponentId TAG_DCE_BINDING_NAME = 101; const ComponentId TAG_DCE_NO_PIPES = 102; const ComponentId TAG_DCE_SEC_MECH = 103; // Security Service The following is the description of our proposed supplement to CORBA core specification. We add one component into module IOP: const ComponentId TAG_AIOR_LOGICALNAME = XXX; // XXX is an undetermined ComponentId. The TAG_AIOR_LOGICALNAME component has an associated value of type string encoded as a CDR encapsulation. We have not defined the interface of mapping logical names to regular IOR because now this function is local and its interoperability is not necessary. But if two or more SPs want to exchange their mapping items to provide more intelegent services, we may need to define the coresponding interfaces.
CORBA 3, chapter 13.8, defines the Codec interface to encode arbitrary data values into CORBA::OctetSeq "blobs" and vice versa. This interface can be used, e.g., to supply and retrieve ServiceContext data using the PortableInterceptor interfaces. In practice, the Codec interface is also being used for data serialization, i.e., to store and retrieve arbitrary values in files or other databases. However, the interface is deficient in that it does not consider all possible variables that are needed for interoperability. It supports setting the CDR version that is to be used, but neglects byteorder and codeset settings. Consequently, the encoded values are platform-specific. If a value was encoded on a little-endian system, it will not decode, or worse, decode erroneously, on a big-endian system. The same caveats apply to codesets, e.g., when an ISO-8859-1 encoded blob is decoded using UTF-8 or Windows-1252. To support interoperability, the Codec interface needs to be extended. My recommendation is to extend the CodecFactory interface, so that it supports creating CDR version-, byteorder-, and codeset-specific Codec instances, either supplying user- provided values for each, or informing the user about chosen defaults. Example: module IOP { const EncodingFormat ENCODING_DEFAULT = -1; typedef short ByteorderFormat; const ByteorderFormat BYTEORDER_DEFAULT = -1; const ByteorderFormat BYTEORDER_BIGENDIAN = 0; const ByteorderFormat BYTEORDER_LITTLEENDIAN = 1; struct EncodingExt { EncodingFormat format; octet major_version; // set to 0 for default octet minor_version; ByteorderFormat byteorder; CONV_FRAME::CodeSetId char_data; // set to 0 for default CONV_FRAME::CodeSetId wchar_data; // set to 0 for default }; local interface CodecFactory { // create_codec remains as before Codec create_codec_ext (inout EncodingExt enc) raises (UnknownEncoding); }; }; The create_codec_ext operation would create an appropriate Codec instance, if available; it will then set all "default" members of the EncodingExt structure to their actual values, so that the application can store this information along with any encoded values. One potential criticism of the above is that the encoding format's parameters depend on the encoding format. For example, there may be encoding formats that are byteorder-independent, or that consistently use UTF-32 for strings, thus not needing codeset parameters. Also, they may use wildly different versioning. So a "better" solution might involve passing the EncodingFormat, and an Any with a format-specific data type. That could look like: module GIOP { typedef short ByteorderFormat; const ByteorderFormat BYTEORDER_DEFAULT = -1; const ByteorderFormat BYTEORDER_BIGENDIAN = 0; const ByteorderFormat BYTEORDER_LITTLEENDIAN = 1; struct CDREncodingParameters { octet major_version; // set to 0 for default octet minor_version; ByteorderFormat byteorder; CONV_FRAME::CodeSetId char_data; // set to 0 for default CONV_FRAME::CodeSetId wchar_data; // set to 0 for default }; }; module IOP { const EncodingFormat ENCODING_DEFAULT = -1; local interface CodecFactory { // create_codec remains as before Codec create_codec_ext (inout EncodingFormat format, inout Any parameters) raises (UnknownEncoding); }; }; Once we have consensus on the approach, I will gladly volunteer to come up with a full set of editing instructions
A lot of the methods on the POA which have USE_DEFAULT_SERVANT or USE_SERVANT_MANAGER as policies don't describe in detail what should happen when one of these policies is set, but no default servant/servant manager is set. For example reference_to_servant, when USE_DEFAULT_SERVANT is set and default servant is registered we return the default servant, but what when no default servant is set, is then the ObjectNotActive the correct exception? Shouldn't this be something like a system exception (bad inv order, obj adapter or something like that?)
Add a typedef for the POAManager id and use this throughout the spec for POAManager, POAManagerFactory and IORInterceptor add typedef string POAManagerId change in POAManager string get_id(); to POAManagerId get_id(); Or better (see other issue). readonly attribute POAManagerId the_id;
I would propose to change in the POAManager the following: State get_state(); string get_id(); to readonly attribute State the_state; readonly attribute string the_id; The get method just hide the fact that this are readonly attributes
The argument of the set_servant call has a small typo, it must be p_servant to match the full IDL spec some pages further
Given a property P defined by type B as PROP_NORMAL, two types T1 and T2 inherit from B but each strengthens the mode to PROP_READONLY and PROP_MANDATORY respectively. Then is there an implied strengthening to PROP_MANDATORY_READONLY in a further derived type T3 which inherits from both T1 and T2? Related to this, the OMG spec has nothing to say about waht exception should be raised by an attempted "weakening" of a property mode by a sub-type or exactly what is construed as a "weakening" with multiple inheritance. Another slightly different senario is: Given a property P defined by type B as PROP_READONLY, two types T1 and T2 inherit from B with one of them "strengthening" the mode of B to PROP_MANDATORY_READONLY. Is deriving a type T3 from both T1 and T2 legal?
The POA state inactive is not used consistent. On several places it is called deactivated instead of inactive. For example in 11.3.8.2, in the transient bullet, it mentions: "Once the POA's POAManager enters the dactivated state". Chapter 11.3.2.1 describes clearly the states are: active, inactive, holding and discarding. I would propose to scan the complete spec for these incorrect POA Manager state.
The grammar definition for valuetype <state_member> via the rule <declarators> includes <complex_declarator>. It should be clarified whether valuetype state members are intended to include <array_declarator>. IMHO clarification is needed as state members are usually mapped to accessor methods in programming languages. If permissible, the accessor methods would return a complex type.
The spec describes respository_id which should be repository_id. Is on two places, in 4.3.14 and 4.3
The overview of all system exceptions is missing several ones which seem to be availalble in https://www.omg.org/docs/omg/03-01-04 For example NO_IMPLEMENT_TABLE minor code 8 is missing
The "operation" field in the RequestHeader_1_2 struct is a string, which implies that it should be subject to code set conversion. However, existing practice seem to be that it is not converted, and there are other factors which could make it difficult for implementations to convert it. In addition, since the operation name is based on IDL/ASCII, conversion doesn't necessarily make sense. The easiest remedy would be to specify this as an exception in the text of the spec. The "correct" remedy would probably be to change the operation field from "string" to "sequence<octet>". This could cause problems at some point, but it might not break too much since the CDR encodings are the same.
In the CORBA specification, chapter 5 (Value Type Semantics), section 5.5 (Custom Marshalling), defines sequences of primitive types in the CORBA module, i.e., CORBA::StringSeq et al. Some of these types are then used by the DynamicAny and Portable Interceptor chapters. The presence of these typedefs in section 5.5 seems to imply that they only need to be defined if the ORB implements custom marshalling -- a feature still lacking in some open-source and commercial ORBs. In my experience, having worked with multiple ORBs, many of them do not provide the complete set of typedefs in their "orb.idl" file. Many ORBs only provide a limited set, usually, the set that is exercised by the other ORB features (such as PI). This implies that most ORBs added these typedefs on an "as needed" basis instead of simply referring to section 5.5. I suggest to move these typedefs from section 5.5 into chapter 4 (ORB interface), e.g., into section 4.2 (ORB operations) to highlight that these types should be present even if custom marshalling is not implemented by the ORB. Proposed resolution: In section 5.5.2 (Marshalling Streams), cut the type definitions, starting with AnySeq, up to and including WStringSeq. In section 4.2, in the IDL code fragment, at the beginning of the CORBA module, paste the type definitions cut above.
In the CORBA specification dated 04-03-12, the last two paragraphs on page 15-33 (section 15.4.1) describe the use of MARSHAL minor codes 7 and 8. However, this use of these minor codes is not reflected in the table of minor codes on page A-11 (appendix A). Furthermore, MARSHAL minor code 7 has also been assigned (at an earlier date?) to an issue resolved in the Java to IDL specification dated 03-09-04 (see page 1-50 / end of section 1.5.1.5). This use of minor code 7 is reflected in the table in the CORBA specification. However minor code 10, which is also specified in the same section in the Java to IDL specification, is not documented in the CORBA specification. In summary, MARSHAL minor code 7 is double-booked, whilst minor codes 8 (used in the CORBA specification) and 10 (used by the Java to IDL specification) are not documented in the table of codes. Proposed solution: Change section 15.4.1 to define the use of MARSHAL minor code 9 (in addition to minor code 8), instead of MARSHAL minor code 7. Update the table of minor codes on page A-11 with the definitions of MARSHAL minor codes 8, 9 and 10.
In section 2.10.1.1, page 22-26 (my copy is formal/04-03-01), enumerated item 3, second bullet, the text reads "232-1 - the maximum value for unsigned long [...]". The "32" needs to be in superscript, i.e., to indicate "2 to the power of 32 minus 1". The same typo exists in section 2.10.1.2, page 22-28, fourth paragraph, second bullet (at the top of the page).
Minor formatting issue in: abstract valuetype Pollable { boolean is_ready( in unsigned long timeout ); PollableSet create_pollable_set( ); }; boolean is_ready is in the wrong font in the idl overview
Update: struct IOR { string type_id; sequence <TaggedProfile> profiles; }; to struct IOR { string type_id; TaggedProfileSeq profiles; }; And also use CORBA::OctectSeq instead of sequence<octet>
The is an error in the ServiceDetail struct. service_detail is listed twice, the first one should be removed. struct ServiceDetail { ServiceDetailType service_detail_type; sequence <octet> service_detail; ServiceDetailData service_detail; };
Struct ServiceInformation is wrong, the sequence<> lines should be removed. struct ServiceInformation { sequence <ServiceOption> service_options; ServiceOptionSeq service_options; sequence <ServiceDetail> service_details; ServiceDetailSeq service_details; };
The spec describes that anonymous types are deprecated and will be removed in the future (as below), but this is used throughout the spec. Before deprecating this fully, update the spec to not used anonymous types: >From 3.11.6 IDL currently permits the use of anonymous types in a number of places. For example: struct Foo { long value; sequence<Foo> chain; // Legal (but deprecated) } Anonymous types cause a number of problems for language mappings and are therefore deprecated by this specification. Anonymous types will be removed in a future version, so new IDL should avoid use of anonymous types and use a typedef to name such types instead. Compilers need not issue a warning if a deprecated construct is encountered.
In the draft 3.1 spec chapter 21.7 says the following: An Interceptor's behaviour may itself be modified by one or more Interceptor Policies. These Policy objects are created using a call to ORB::create_policy and are associated with an Interceptor during registration (see Section 21.7.2, ORBInitInfo Interface). All Policy interfaces defined in this section are local. The ORB can be accesed via the implicit get_orb operation of ORBInitInfo. The ORBInitInfo is passed on the pre_init and post_init call of the ORBInitializer but what should be the orb in the pre_init call? The orb is not initialized at that moment? Shouldn't it say that calling get_orb on the ORBInitInfo in the pre_init call gives the default exception that is given when get_orb is called on a local object?
The draft document says the following in 21.9.1. The description about the type of exceptions sounds very vague. Shouldn't the spec be more detailed, which type of exceptions should be ignored specifically? Any exceptional return from the invocation of any operation of the ORBInitializer interface other than those resulting from the failure to instantiate a portable interceptor object shall result in the abandonment of the ORB initialization and destruction of the ORB. Any ORBInitializer implementation that needs the ORB to ignore any thrown exceptions can simply catch and discard them itself.
In case get_slot is called from withing an ORB itializer chapter 21.4.3.1 says a BAD_INV_ORDER with minor code 10 is thrown, this should be 14 as mentioned also in 21.7.2.11
This corba spec describes POAManagerFactory. I have been searching on the web and it seems for example Orbacus has the possibility to do a resolve_initial_references ("POAManager"). This seems not possible with the latest corba spec. This seems an usefull extension. The only option there is now is to get the RootPOA, get from there the POAManagerFactory and use that again.
The minor code for add_reply_service_context is not correct. The spec says: Indicates the behavior of this operation when a service context already exists with the given ID. If false, then BAD_INV_ORDER with a standard minor code of 11 is raised. If true, then the existing service context is replaced by the new one. The minor code should be 15.
The tags for unreliable multicast are missing. // The following are defined in 03-01-11 const ProfileId TAG_UIPMC = 3; const ComponentId TAG_GROUP = 39; const ComponentId TAG_GROUP_IIOP = 40;
In the Interceptor interface there is a destroy method which can throw a system exception just like all other corba calls. What is the behaviour when the orb shutdown is done and an Interceptor::destroy() call throws an exception? Should the ORB ignore this exception and continue the shutdown or should it return the exception to the caller. I would except ignore the exception and continue but the spec doesn't describe the behaviour.
There are some inconsistent idl declarations in CORBA3.0.2 Chapter 9(with editorial update version) 1?page 9-10: the idl declaration of DynAnyFactory is not the same as the idl declared earlier(page 9-9). It seems that three new fuctions have been left out. 2?Page 9-5: DynUnion should have a member fuction is_set_to_default_member, which is declared on page 9-20
CORBA3.0.2(formal/02-12-02), chapter 7.2.1, says "The implicit object reference operations non_existent, is_a, repository_id and get_interface may be invoked using DII. No other implicit object reference operations may be invoked via DII." However, I think we should add "get_component" to this list of allowable operations. Or else we can't use some features of CCM via DII, because the implementation of get_component resides on the server side.
The NVList has a count, which is defined as long, it would be better to make this an unsigned long. This has impact on ORB::create_list, change the type of argumetn count to unsigned long. Also update NVList::get_count to have an unsigned long argument.
CORBA 2.4 introduced forward declarations for IDL structures and unions in support of recursive structures, deprecating the prior practice of anonymous types. Also allowed were sequences of forward-declared structures ("incomplete types"), which could then be used as members in defining the structure. Currently, it is only allowed to use incomplete types in the actual definition of the type itself. As an example in section 3.11.2.3 demonstrates, this does allow indirect recursion -- but only if the incomplete types are nested, as in [first example] struct Foo; typedef sequence<Foo> FooSeq; struct Foo { struct Bar { FooSeq fs; } b; }; Specifically not allowed -- and this is the point of this issue -- is the seemingly more intuitive definition of [second example] struct Foo; typedef sequence<Foo> FooSeq; struct Bar { FooSeq fs; }; struct Foo { Bar b; }; Currently, the spec says that, "sequence members that are recursive must refer to an incomplete type currently under definition," and thus Bar is not allowed to use FooSeq as a member. However, the second example is, in effect, no different than the first. In the first example, "Foo::Bar" is a well-defined stand-alone type that can be used elsewhere (e.g., as a structure member or operation parameter). If a developer intends to use both structures, the second example makes this much clearer, as it syntactically elevates "Foo::Bar" from a mere sub-type to an "independent" structure. Therefore, I would like to change the current wording of section 3.11.2.3 to allow the second example. A proposed update is below. This issue is all the more urgent because another available specification, the "Deployment and Configuration of Component-based Distributed Applications," depends on it, by using two IDL structures that mutually and indirectly recurse, effectively using [third example] struct Package; typedef sequence<Package> PackageSeq; struct Assembly; typedef sequence<Assembly> AssemblySeq; struct Package { AssemblySeq as; }; struct Assembly { PackageSeq ps; }; In reality, the IDL in question is a bit more complicated, using some intermediate structures, which makes rewriting the IDL without this mutual recursion impractical and non-intuitive -- also because both "Package" and "Assembly" are meant to be potentially top-level, stand-alone items. Some might argue that the IDL restriction existed before the "Deployment" specification was adopted, and that CORBA should not be changed just because some later spec willingly (or rather, naively) used buggy IDL. So let me make some more arguments in favor of my request. First, as explained above, IDL already allows for indirect recursion. It just requires nesting. Second, defining structures as a "side-effect" of a member declaration is ugly, only marginally better than anonymous types. Allowing the type definition of a member to stand by itself is, in my opinion, much cleaner. Third, indirect recursion between non-nested types is no more difficult to implement in an ORB than indirect recursion between nested types. In fact, some existing ORB products already have no problem with indirect recursion, and are able to compile the IDL from the third example, resulting in correct code. The code works fine with Mico, TAO, JacORB and Combat, all of which apparently neglect to implement the check that "sequence members that are recursive must refer to an incomplete type currently under definition." OmniORB does issue a diagnostic, but simply removing the check, and making another trivial change to its IDL compiler, results in correct C++ code. Four, the existing IDL syntax, TypeCodes, CDR marshalling rules, and Interface Repository all allow indirect recursion to exist. In fact, it is already possible to create the above data types using the Interface Repository and TypeCode interfaces -- as well as to create instances using DynamicAny, and to marshal them. With this background, I suggest to remove the statement that prevents indirect recursion between non-nested structures and unions. Proposed resolution: In section 3.12.2.3, change paragraphs (counting each IDL code example as a single paragraph) 10 to 12 (page 3-42) from If a recursive structure or union member is used, sequence members that are recursive must refer to an incomplete type currently under definition. For example struct Foo; typedef sequence<Foo> FooSeq; struct Bar { long value; FooSeq chain; // Illegal, Foo is not an enclosing }; // struct or union. Compilers shall issue a diagnostic if this rule is violated. to If a sequence member of a structure or union refers to an incomplete type, the structure or union itself remains incomplete until the member's definition is completed. For example struct Foo; typedef sequence<Foo> FooSeq; struct Bar { long value; FooSeq chain; // Use of incomplete type }; // Bar itself remains incomplete struct Foo { // ... }; // Foo and Bar are complete Thank you for listening. Also thanks to Jeff Parsons and Boris Kolpakov from Vanderbilt University for researching this issue. We, the submitters of the "Deployment" specification, genuinely believe that indirect recursion is useful, and its lack (and having to work around) would take considerable value from the specification. I am uncomfortable arguing to change another spec to fix ours. But one spec has to change, and I believe that indirect recursion is a useful feature that already (unwillingly) exists in many ORBs, that it is no more problematic to implement than the existing means of recursion, and that the resulting data types are already valid when obtained from the TypeCode or Interface Repository interfaces. Considering the conflict of available specifications, I am tempted to flag this issue as urgent. Andrew, is that even possible, given that there is no active Core RTF?
Section 11.3.1 "The Servant IDL Type" defines the default implementations of get_interface, is_a, and non_existent. However, we should define the default implementation of "get_component" as well because this fuction is also an ORB-mediated implicit object reference operation. By default, this function returns a nil reference. When the object is a component or a facet, as other default implementations, this operation can be overridden by the servant's implementation.
Section 9.2.9 says "A reference to a DynValueCommon interface (and interfaces derived from it) exhibit the same sharing semantics as the underlying valuetype that it represents.", which defines the sharing semantics of DynAny. However, I think its precondition is that valuetype's sharing semantics can be preserved in Any. DynAny is usually used with Any, converted from or to Any. If Any can't preserve sharing semantics, there is no necessary for DynAny to keep them. Suppose we use a struct which consists of several valuetypes to store a graph. In order to ensure the correctness of an application based on DII/DSI, converting this struct to Any and then to DynAny should produce an identical graph. However, if Any can't preserve sharing semantics, this goal is impossible. Any's sharing semantics focuses on valuetype conversion, because we don't concern the concrete internal implementation of Any. It means that when we extracting valuetypes from an Any or converting an Any contains valuetypes into a DynAny, sharing semantics should be preserved. For example, different Anys contain same valuetype only produce one valuetype instance when their contents are extracted. We can implement this by the help of a global valuetype manager. To sum up, the sharing semantics of valuetype can be divided into three layers: valuetype itself, Any and DynAny. All of them constitute a complete hierarchy. Only after each layer has been implemented, we are able to ensure that applications that use the DII and DSI can correctly view and preserve the semantics of the valuetype graph. Because Any's sharing semantics is very fundamental, it is necessary for us to clarify it in the specification, though we haven't special chapter/section on Any. We can add it to Chapter 5 "Value Type Semantics". Section 5.2.4.2 only defined sharing semantics in the layer of valuetype itself. We should say something about sharing semantics in the other two layers at the end of this section.
The CORBA spec describes the following about the wait_for_completion parameter of the POA::destroy call: The wait_for_completion parameter is handled as follows: � If wait_for_completion is TRUE and the current thread is not in an invocation context dispatched from some POA belonging to the same ORB as this POA, the destroy operation returns only after all active requests have completed and all invocations of etherealize have completed. � If wait_for_completion is TRUE and the current thread is in an invocation context dispatched from some POA belonging to the same ORB as this POA, the BAD_INV_ORDER system exception with standard minor code 3 is raised and POA destruction does not occur. We have a use case where we have an ORB with two POA's, A1 and B1, each POA again has a child A2 and B2. In case we get a request for a servant of A2 to destroy POA B2 and we specify TRUE for wait_for_completion then we get an exception back, but this doesn't seem locally. We understand that when we want to destroy A1 when handling a request using a servant of A2 that we get an exception at that moment. We propose the change the description as following: The wait_for_completion parameter is handled as follows: � If wait_for_completion is TRUE and the current thread is not in an invocation context dispatched from some POA that is a child of this POA or from this POA itself, the destroy operation returns only after all active requests have completed and all invocations of etherealize have completed. � If wait_for_completion is TRUE and the current thread is in an invocation context dispatched from some POA that is a child of this POA or from the POA itself, the BAD_INV_ORDER system exception with standard minor code 3 is raised and POA destruction does not occur.
There are some issues with the definition of ExceptionHolder. In 22.16 it is as below, see the raise_exception_with_list, this seems to have two arguments here, in 22.7 there is just one argument. The same problem also appears in the draft 3.1 spec. Also, there is no CORBA::ExceptionList defined in the spec at all, there is Dynamic::ExceptionList but no CORBA::ExceptionList. valuetype ExceptionHolder { void raise_exception() raises (UserExceptionBase); void raise_exception_with_list( in CORBA::ExceptionList exc_list) in Dynamic::ExceptionList exc_list) raises (UserExceptionBase); private boolean is_system_exception; private boolean byte_order;
In the C++ example code of 22.11.3 Messaging::ExceptionHolder_ptr is used, for valuetypes there is no _ptr, the could should read Messaging::ExceptionHolder *
The following methods are not described in this chapter: Object make_object (in string repository_id, in ObjectId id); IOP::TaggedProfileSeq make_profiles (in string repository_id, in ObjectId id); These are mentioned in 21.10.3
C++ as a language is not just the core language but also STL that accompanies with it. There are lots of useful algorithms in STL, but they are not very easily used with the C++ mappings of CORBA Sequences. Step closer to this usability would be to add a member typedef that would tell the type of items the sequence contains - this would allow implementing an STL iterator compliant types more easily. And really nice thing would be if the mapping would have begin() and end() functions like STL containers do.
Regarding the base_interfaces attribute of the Interface Repository (IFR) InterfaceDef and the ExtInterfaceDef interfaces, the CORBA spec has only this to say: "The base_interfaces attribute lists all the interfaces from which this interface inherits." Does that sentence mean that the base_interfaces attribute lists only immediate base interfaces, or does it list *all* base interfaces, i.e., the transitive closure of the inheritance graph (minus the implied Object interface at the root)? I believe it is supposed to be a list of only immediate interfaces, as one can make further calls on the IFR to obtain more information about those bases, including their bases. However, both the FullInterfaceDescription and the ExtFullInterfaceDescription structures also have a base_interfaces member, which is specified as a sequence of repository IDs. Unfortunately, the specification contains no description whatsoever for this member. I argue that unlike the base_interfaces attribute described above, this member can't list only the immediate base interfaces. I believe that the base_interfaces member of the FullInterfaceDescription and the ExtFullInterfaceDescription structures should contain the transitive closure of all base interfaces. These structures are intended to supply *full* interface descriptions, after all. Specifying the base_interfaces as I suggest would match the operations and attributes fields of the same structs, which are already explicitly specified to contain all operations and attributes respectively from the transitive closure of the inheritance graph. Note also that if base_interfaces does not contain the transitive closure of all base interfaces, there's no way to obtain the information from TypeCodes, since names do not appear in TypeCodes in minimum CORBA. I therefore propose that the third paragraph of section 10.5.24.1 of CORBA 3.0.2 be changed from this: "The describe_interface operation returns a FullInterfaceDescription describing the interface, including its operations and attributes. The operations and attributes fields of the FullInterfaceDescription structure include descriptions of all of the operations and attributes in the transitive closure of the inheritance graph of the interface being described." to add a sentence defining the base_interfaces member, like this: "The describe_interface operation returns a FullInterfaceDescription describing the interface, including its operations and attributes. The operations and attributes fields of the FullInterfaceDescription structure include descriptions of all of the operations and attributes in the transitive closure of the inheritance graph of the interface being described. The base_interfaces field of the FullInterfaceDescription structure includes the repository IDs of all the base interfaces in the transitive closure of the inheritance graph of the interface being described, except for the repository ID of the implied Object base interface." Note that even if this change is made, the base_interfaces attribute of InterfaceDef and ExtInterfaceDef can (and should) remain as listing only immediate bases, assuming that's what the spec's original intent was.
For activate_object_with_id it is described that when SYSTEM_ID has been set and the object id was not generated by this system or tis POA we throw a BAD_PARAM, but the minor code is not described. Shouldn't this have an unique minor code?
I implemented CORBA functionality, in that implementation I got some exceptions. I am sending that exceptions list in the below. omniORB: ERROR -- the application attempted to invoke an operation on a nil reference. terminate called after throwing an instance of 'CORBA::INV_OBJREF' Aborted (core dumped) I have some doubts on these exceptions. What is the cause for this exception? How can I solve this exception? Please clarify my doubts.
There was an issue 8969 (Allowing mutual recursion for IDL structures) posted sometime back on CORBA RTF (www.omg.org/issues/issue8969.txt). I am looking for a clarification in the proposed resolution, which allows for the mutual recursion between non-nested structures (CORBA 3.0 specification, section 3.11.2.3). The proposal essentially extends the definition of incompleteness of a struct/union as follows: The original definition was: o A struct/union is termed incomplete until its full definition is provided; that is, until the scope of the struct/union definition is closed by a terminating "}" The introduced proposal added to the original definition: o If a sequence member of a structure or union refers to an incomplete type, the structure or union itself remains incomplete until the member's definition is completed Section 3.11.2.3 also says that "an incomplete type can only appear as the element type of a sequence definition". Question 1: Is following legal under the new scheme? struct Foo; typedef sequence<Foo> FooSeq; struct Bar { FooSeq fs; }; // Bar remains incomplete since it is holding an incomplete sequence type struct FooX { Bar b; // Is this valid with Bar marked incomplete here? }; struct Foo { Bar b; }; // According to the proposal, Foo and Bar are complete now Use of Bar under FooX apparently conflicts with the condition that incomplete type can only appear in a sequence definition. Question 2: Also is it must that there is a mutual recursion between non-nested structures? Consider the following: struct Foo; typedef sequence<Foo> FooSeq; struct Bar { FooSeq fs; }; // Bar remains incomplete struct Foo { long a; }; // Is Bar also complete here when Foo is complete even though Foo doesn't recurse on Bar? Is the above IDL valid under the new proposal? There is no constraint in section 3.11.2.3, which doesn't allow for this so it stands valid as per spec. Was issue 8969 also intended to make such cases valid?
Table 21-1 has the following note: When ClientRequestInfo is passed to send_request, there is an entry in the list for every argument, whether in, inout, or out. But only the in and inout arguments will be available. What is the behaviour when I request an out value? It says only that in/inout are available, but when I have an argument that is of out and I do get the value, do I then get an empty value (which could lead to a crash when using it), do I get an exception? That must be clearly specified by the spec
The use of the '/' character to identify the object key component of a corbaloc URL is ambiguous where a protocol address also contains the character. Example: corbaloc:uiop:/tmp/uiop/xx/steve This could represent either a uiop address '/tmp/uiop' and an object key 'xx/steve/ or a uiop address '/tmp/uiop/xx' and an object key 'steve'. Suggest removing the '/' character from the list of non excaped object key characters (bottom of page 13-26)to resolve this ambiguity. The corbaloc would then become: corbaloc:uiop:/tmp/uiop/xx%27steve
In 15.4.2 and 16.4.1 get_implementation is mentioned, but this method is nowhere else in the spec. Should this method be there? So far as I can see this is deprecated and should be removed.
Proposal to change PortableInterceptor::ReplyStatus to a real enum. Now it is a short with constant values, but this means there is no real relationship between the type and the possible values as possible with an enum. With for example C++ we then can let the compiler check if we don't use incorrect values. module PortableInterceptor { enum ReplyStatus { SUCCESSFUL, SYSTEM_EXCEPTION, USER_EXCEPTION, LOCATION_FORWARD, TRANSPORT_RETRY, UNKNOWN }; };
Proposal to change PortableInterceptor::AdapterState to a real enum. Now it is a short with constant values, but this means there is no real relationship between the type and the possible values as possible with an enum. With for example C++ we then can let the compiler check if we don't use incorrect values. module PortableInterceptor { enum AdapterState { HOLDING, ACTIVE, DISCARDING, INACTIVE, NON_EXISTENT }; };
Third line of 23.1.3.4, ACTIVE must be bold
The CORBA/e FTF slightly changed the definition of Invalid Policies to: exception InvalidPolicies { UShortSeq indices; }; since this avoids the use of an anonymous sequence type, consider changing it (also for consistency).
CORBA/e FTF (issue 11331): removed mention of (deprecated) function get_implementation from text. Consider making same change for consistency
The MIOP does not provide an analogous operation to PortableServer::POA::create_POA() for the GOA (i.e. there is no PortableGroup::GOA::create_GOA). The lack of an operation of this nature prevents the ability for an interface (i.e. servant) to subscribe to multiple (i.e. more than one) multicast group. To specify to a POA to allow multiple entries in its Active Object Map, the POAs IdUniquenessPolicy would have to be set to MULTIPLE_ID. This can only be done via the POAs create_POA operation. Since there is no GOA create_GOA operation, a GOAs IdUniquenessPolicy cannot be set to MULTIPLE_ID, which prevents a servant from being able to be subscribed to more than one multicast group. I don't know if the OMG explicitly wants to prevent this capability, thus purposely leaving it out of the MIOP specification, or if this is simply an overlooked issue.
This section defines struct PolicyValue { CORBA::PolicyType ptype; sequence<octet> pvalue; }; Which should be as below because anonymous types are deprecated struct PolicyValue { CORBA::PolicyType ptype; CORBA::OctetSeq pvalue; };
The CORBA spec defines the following types to proposage messaging qos. This is really nothing more then propagating policies values. struct PolicyValue { CORBA::PolicyType ptype; sequence<octet> pvalue; }; typedef sequence<PolicyValue> PolicyValueSeq; This is now in the Messaging module, but the propagation of policy values is something that we want to use for ZIOP but also seems usable for other libraries. Instead of duplicating this struct to different modules I propose to move this to the IOP module.
The corba spec defines a lot of policies. In 4.8.5 client exposed policies are listed. We do have several of them, also policies could be applied at several levels, but some of them can't be applied to each level. To our idea the scope at which policies can be applied should not only be in the possible, but also part of the policy itself. That way application code and the corba orb could check this. Maybe add this to policy typedef unsigned long PolicyScope; const PolicyScope POLICY_SCOPE_OBJECT = 0x01; const PolicyScope POLICY_SCOPE_CURRENT = 0x02; const PolicyScope POLICY_SCOPE_SCOPE = 0x04; const PolicyScope POLICY_SCOPE_POA = 0x08; const PolicyScore POLICY_SCOPE_CLIENT_EXPOSED = 0x10; Then add to the interface Policy readonly attribute PolicyScope policy_scope; This attribute can then be set in the policy with the values above as bitmask. This can be documented clearly in the documentation, orbs can check this, etc.
This chapter defines register_orb_initializer. This itself is ok, but at the moment we have a 24*7 system and we get a new ORBInitializer shipped in for example a DLL we maybe want to get rid of a certain orbinitializer that we registered earlier. This is currently not possible, we propose to add an unregister_orb_initializer which makes it possible to unregister an orbinitializer again
ServiceContext is defined as: struct ServiceContext { ServiceId context_id; sequence <octet> context_data; }; Anonymous types are deprecated, this should be struct ServiceContext { ServiceId context_id; CORBA::OctetSeq context_data; };
For a 24x7 system that doesn't shutdown and gets reconfigured it would be useful if we could for example change "-ORBDefaultInitRef" after the ORB has been initialized. That then would be used for any objects resolved after that. Maybe we could add CORBA::ORB::arg_list (inout arg_list argv); Which would change the arglist
We see more and more use of unicode. It happens more and more that users have code that gets unicode (wchar) commandline arguments. In order to smoothen corba usage for these users we propose to add interface ORB { Object string_to_object ( in wstring str ); };
16.10 lists register_initial_reference. It would be usefull for dynamic systems to also have a unregister_initial_reference (in ObjectId id).
There is lack of multiplex publisher port that would mimic functionality of multiplex receptacle. Having multiplex publisher port it would be easier to connect with dynamically created event consumers such that each consumer would have its own private communication channel with the publisher. In case of dynamically created consumers it is not possible to foresee the number of publisher ports required. For synchronous communication the elegant solution is a component with a multiplex receptacle for which we have separate communication channels.
The document title in PDF metadata is "untitled", should be "Common Object Request Broker Architecture (CORBA) Specification"
Is: A character literal is one or more characters enclosed in single quotes, as in �x.� Should be: A character literal is one or more characters enclosed in single quotes, as in 'x'. (note that the present version uses curly quotes and the dot is probably misplaced)
The rule number (85) is indented, the rule number is not aligned with other rule numbers.
the specification already deprecated anonymous types, but to our idea it would be time to update the specification to say that anonymous types are illegal and remove all references to them
The ORB is intended to be a local object, it is not to be used outside of the process, so it should be a local interface
The spec does not clearly describe the relationship between connectors and components (inheritance?) and homes (manageability). >From paragraph 7.4 (programming model for connectors) we can conclude the following: 1. connectors are derived from CCMObject 2. connectors (can) have a (keyless) Home The formal spec in the earlier paragraphs of chapter however does not seem to mention any of this or of the consequences like: a) can we explicitly define a connector as the managed component of a Home? b) can we define explicit factories for connectors in a Home managing that connector? c) can we declare a component as an explicit derivative of a connector? I think the answers to a) and b) should be yes. This should be clearly described in the spec. In principal the answer to c) could also be yes but I think that is a bad idea since the connector is definitely not meant to be used as a general purpose component. I feel this should actually be explicitly prohibited by the spec.
It seems that the last and 4th-to-last bullets both describe the Wstring type. Thus, one should suffice.
The context has to be define as local interface instead of a regular interface
For several cases it would be helpful to have a: Policy create_policy( in PolicyType type) raises(PolicyError); The name of the method has to change, to not conflict with the existing method
There are two typo's in section A.4 on page 495. 1 SERVENT_RETENTION_POLICY_ID should be SERVANT_RETENTION_POLICY_ID 2 PortableServer::ServentRetentionPolicy should be PortableServer::ServantRetentionPolicy
In the ZIOP 1.0 specification, the IDL in Annex A has: typedef unsigned short CompressorId { }; The braces are invalid and should be removed.
In the ZIOP 1.0 specification, Annex A has: Compressor get_compressor( in CompressorId compressor_id, in CompressorLevel compression_level) raises (UnknownCompressorId); CompressorLevel should be CompressionLevel.
Section 17.3.1 of CORBA 3.1 / 3.2 says: 17.3.1 Structures PolicyValue This structure contains the value corresponding to a Policy of the PolicyType indicated by its ptype. This representation allows the compact transmission of QoS policies within IORs and Service Contexts. **The format of pvalue for each type is given in the specification of that Policy.** When the ZIOP 1.0 specification describes the ZIOP policies, it does not give the format for pvalue.
The ZIOP body format contains the original length of the compressed data, which is important because it allows the compressor to efficiently allocate a buffer to uncompress it. Unfortunately, the Compressor::decompress() operation is not given that size, meaning that it has to guess how big the uncompressed data will be. The original data size should be given to the decompress() operation. One way to do that without changing the operation signature would be to specify that the inout Buffer target sequence should have its length pre-populated to the expected size.