Dynamic Proxies?
Why Does the OSID Runtime Use Dynamic Proxies?
While it is a royal pita to sift through the Java exception stacks, there's some good reasons for this.
This is a behavior of our Java implementation of the OsidRuntimeManager interface and called for in the interface definition. The OSIDs do tightly specify the following:
- no nulls are to be passed or returned
- only those errors specified in the interface definition may be thrown (or those specified on the Java OSID Binding)
- the OSID Providers are encapsulated and implementations not to be accessed by OSID Consumers
Fail Fast
There is a set of interoperability problems that result from unexpected out of band agreements between applications and implementations. These agreements include:
- casting an interface back into its implementing object
- directly accessing implementation resources
- using extra exceptions and/or nulls to pass extra interface not defined in the specification
These contract violations are quickly forgotten and are left to the person who experiences a failure when swapping something out. "Oh, you need to subclass my implementation and make your HashMap public if you want to use my service." Why even bother.
New service developers who operate on both the application and service implementations simultaneously can often miss the nature of a service boundary. Service contracts present themselves as Java interfaces in the code. When working both sides of the service boundary, there is a strong tendency to see the it as an obstacle to be punched through without consideration to the effects on integration. From the sole developer's perspective, that is their object down there and may not see why there would be a problem in wiring the application directly to it.
Integration occurs after development and the interoperability scenarios are not generally understood at the time of development. "No one told me that this was a requirement." The services provide the guides in which development can occur in such a way that can be leveraged and integrated later. In order for integration to succeed, the service boundary has to be respected as a great wall between consumers and providers. Otherwise, why bother?
This OsidRuntimeManager implementation prevents and catches some of these interoperability problems. A developer running into a contract violation exception is something that should be identified quickly because it is a sign of a conceptual misunderstanding that's better addressed before there's a huge pile of code produced.
The contract violations are to assign blame and this keeps honest as well.
Version Management
The OSID Specifications evolve slowly. There will be additions and changes that cause compatibility problems between older and newer code. OsidRuntimeManager provides the hooks for version negotiation to preserve compatibility across minor releases.
Runtime Management
TBD.
Performance
A method invocation through the OsidRuntime proxy adds approximately 150µs per call for repeated calls. The initial call may be significantly higher but varies greatly upon the kind of interface due to both the JVM and OsidRuntimeManager implementation behaviors.
We wouldn't use OSIDs for hard core number crunching. However, as an encapsulation tool for databases, servers, and other software modules it's a small price to pay.
Performance is a concern for layering OSIDs. An OSID stack 100 deep sounds a bit extreme. However, a performance cost should be judged against the complexity at hand. Adding an extra millisecond or two to a manageable and organized stack may be a drop in the bucket compared to the amount of heavy lifting accomplished within the OSID Providers.