I forget how long ago it is that the OpenEdge OpenClient was released. It must be easily close on 10 years, but I am willing to accept that may be an exaggeration. OpenClient is a cool technology. For the uninitiated, the OpenClient is a very powerful library of code and a set of tools that allows .NET, Java and WebService access to the OpenEdge AppServer. It allows you to build your business logic in the OpenEdge ABL and access it from whatever client you choose.
In order for the OpenClient to be able to connect to the AppServer, make a call and return the output parameters, there is a certain amount of code that you need on the client (Java or .NET) that wraps the OpenClient library. In an effort to simplify the process of writing that code, OpenEdge includes a utility called "ProxyGen" that parses the OpenEdge ABL code and generates a proxy class that wraps all of the code needed and exposes it as a simple method call. Once you have generated the proxy, you simply include the generated class in your code (either as a .jar or a .NET assembly, or even directly as source code) and you can make whatever call you need.
The problem with ProxyGen is that you have to regenerate the proxy and potentially rebuild the client each time the ABL procedure changes its signature. That would be okay if the ProDataset and Temp-Table definitions were not part of the signature, but they are and adding a field to a temp-table should not cause a proxy to break.
"Hang on, Bruce," I can hear you say, "Why is the signature of the temp-table not a change to the signature to the API?" I'm not saying that it isn't, but I am saying that it is far more difficult to avoid making this mistake. Here's why:
Typically, temp-tables that form part of the in-memory data model are defined in include files and then used in procedures and classes as in the attached diagram.
Let's assume that Procedure1.p and Procedure2.p are deployed to the AppServer and that Procedure1.p accepts the temp-table as an input parameter and Procedure2.p uses it as an input-output parameter.
As a result of a necessary change to the in-memory data model, a field or two are added to the temp-table definition for the purposes of the Class1.cls and Class2.cls. As part of the build, the code is recompiled and the new code deployment to the AppServer is completed successfully. Note that there has been no planned change to the Procedure1.p and Procedure2.p.
The problem that we now face is that the proxies that were generated for the Procedure1.p and Procedure2.p are now invalid. The temp-table definition is no longer correct and a run-time error will now occur for the client when these procedures are called.
Another problem with proxies is the complexity associated with unit-testing and verifying each individual proxy. Each time a proxy is changed, each of the unit tests for each call in the proxy has to be rerun and retested. There is no way to generically test them to verify the Java/.NET code.
In one of the more recent versions of OpenClient, the API that the OpenClient uses is documented so that it is now possible to dynamically construct the proxy calls at run-time. The overarching benefit in this lies in the ability to now define the temp-table definitions on the fly. The Java/.NET code can now define the temp-table dynamically at run-time so that if a change is made to the definition, the client can deal with the change with no impact on the OpenClient source code.
This functionality is, in fact, so powerful that the entire signature, including all parameter definitions, can be discovered and defined at run-time.
This concept becomes even more interesting as you consider using it for WebServices. ProxyGen can generate the WSDL for a procedure that is to be exposed as a WebService, although it suffers from the same issues if the signature changes. The dynamic OpenClient API makes it possible to dynamically generate the WSDL at run-time from the procedure. Obviously there are overheads associated with auto-discovering a procedure's signature. It makes sense, therefore, to build out this functionality so that the signature discovery is done as seldom as possible.
In a future article I will provide some code samples that show you how to use the Dynamic OpenClient.
UPDATE: I have subsequently made this code sample available. You can refer to it here.