Assemblies and dll versions

Posted by jmls on 04-Sep-2011 02:33

Had a strange problem this weekend, which I thought that I would share and ask for comments

10.2B  - We use the Infragistics controls in our app (MyApp). The App itself is in a memory-mapped prolib file, and we store the dll's for the IG controls in the root directory of our application (c:\myapp) , and use the "-assemblies c:\myapp" startup option.

All has been going well, until we had an application update this weekend.

The application would not start, complaining about the fact that we were trying to load v2119 of the controls, when only v2017 was available. However, the assemblies file was using 2017, and the dll file was v2017.

Could not understand it. Switched back to the old version of the app, everything worked fine. Copied the dlls and assemblies file from the old app directory into the new App, new app still did not work.

Try again. Copied just the app.pl file from old directory to new directory, and things worked again. What ??

Turns out that the dev machine has SP04 on it, which has new versions of the dlls. However, these new versions only exist in the c:\progress\openedge\bin\infragistics\winform directory.

Sure enough, copy the dll from this directory into the root directory of the app, and all is peachy.

I thought that the assemblies.xml file used the directory that the file was in ? So , why does it need the versions in the progress directory ?

On top of that, why did simply switching the prolib file from new to old suddenly make the app work again ? Is the version of the controls stored in the r-code anywhere ?

All Replies

Posted by Admin on 04-Sep-2011 06:13

jmls schrieb:

Had a strange problem this weekend, which I thought that I would share and ask for comments

Not strange at all. But don't worry - you are not the first that got struck by the assembly versions during deployment. If you compile on 10.2B04 you need to deploy on 10.2B04 (or better). PERIOD!

With GUI for .NET there are much stricter rules for R-Code version compatibility than without.

1.) The R-Code contains the fully qualified assembly names of all .NET classes used. And that includes the version number (available during compilation).

2.) The Progress.Data.BindingSource and Progress.Windows.Forms got new (useful) properties in the service packs. What if (accidentialy or by purpose) you turned one of these new properties on and the client runtime does use a version of the ProBindingSource that does not have these properties???

A bit more to read:

http://blog.consultingwerk.de/consultingwerkblog/2011/07/a-few-words-on-openedge-ultracontrols-and-deployment%E2%80%A6/

and

http://blog.consultingwerk.de/consultingwerkblog/2011/07/ultracontrols-net-assemblies-and-deployment-a-follow-up/

Posted by jmls on 04-Sep-2011 07:55

Thanks for the info, Mike.

I was aware that the difference sp had different dll's , but I thought that the version of the dll specified by the assemblies file would be the version compiled into the rcode, not the one in the progres directory.

Posted by Admin on 04-Sep-2011 15:25

but I thought that the version of the dll specified by the assemblies file would be the version compiled into the rcode, not the one in the progres directory.

That was my assumption as well once. But look at it this way:

You are developing with 10.2B02, Infragistics 9.2.20092.2090. You are using a property of an object or a type etc. that was just introduced with that version. If your R-code would try to use 9.2.20092.2017 (10.2B w2ithout SP) your code would run against a version of Infragistics that's missing that new property or type. Can't work - and put's strong typing / compile time validation to absurdly.

However, when Progress (probably backed by Infragistics) says, that the 10.2B04 version of Infragistics (9.2.20092.2119) did not remove and any properties or types then this is a different thing. And Progress says so in the %DLC%\bin\prowin32.exe.config.

In theory you could add entries to that file and add additional compatibility path's - however that sounds like the road to hell to me. I'd rather install the service pack on the runtime, or avoid the service pack in the build environment.

Posted by jmls on 05-Sep-2011 02:22

I think that you are missing my point.

If I have v1 of a dll in c:\myapp,

if I have v2 of a dll in c:\progress\bin

if I have -assemblies c:\myapp

if I compile c:\myapp\myprog.cls

why would the resulting myprog.r have v2 in the rcode ? I want v1, I have v1 in my folder, and I have my assemblies file pointing to the v1 dll in my directory

Posted by Peter Judge on 06-Sep-2011 07:30

What's in the assemblies.xml file? Toolbox.xml?

-- peter

Posted by jmls on 06-Sep-2011 07:50

nope. No toolbox.xml

[snip]

Posted by Admin on 06-Sep-2011 07:55

I assume that the Progress runtime has a strong preference (search order) for Assemblies in the %DLC%\bin\... directory.

Posted by jmls on 06-Sep-2011 08:20

And that can't be right - it should search -assemblies directory

first, then DLC\bin, surely ?

On 6 September 2011 13:55, Mike Fechner

Posted by Admin on 06-Sep-2011 08:25

And that can't be right - it should search -assemblies directory

From your/our point probably yes. But they need to provide support for it. And fixing the Infragistics version to the runtime version reduces the risk/amount of testing required.

Just a guess. But it may also be just an error

Posted by Peter Judge on 06-Sep-2011 08:51

mikefe wrote:

And that can't be right - it should search -assemblies directory

From your/our point probably yes. But they need to provide support for it. And fixing the Infragistics version to the runtime version reduces the risk/amount of testing required.

Just a guess. But it may also be just an error

This question was asked a couple of years ago ...  http://communities.progress.com/pcom/message/68891#68891 . Take a look at my and Shelley's replies: http://communities.progress.com/pcom/message/68914#68914

-- peter

Posted by Garry Hall on 06-Sep-2011 08:58

Some technical information on the AVM's assembly loading:

The prowin32.exe.config is used only by the CLR to resolve assemblies. The AVM essentially ignores it.

An explanation of assembly resolution in the AVM:

When the information for an assembly is read from the assemblies.xml file, the AVM makes calls into .NET to load the assembly (Assembly.Load()). The AVM passes it the AssemblyName it constructed from the entry in the assemblies.xml file. Control is thus passed to the CLR to load the assembly, and the AVM is at the mercy of .NET's assembly loading rules. The first place the CLR looks is in the GAC, and if it fails to find it there, then it probes below the executable's directory (DLC/bin in our case). This is documented behaviour of .NET. There are nuances to this if you read the .NET doc, but I don't believe they are relevant to this conversation.

If the CLR fails to find the assembly in either of these places, the AVM is notified of the failure to resolve the assembly. The AVM then directs the CLR to look in the -assemblies directory (the current working directory by default).

What I think is happening here:

The assemblies.xml file contains the .2017 assembly names. The AVM tells the CLR to load the assembly. The CLR then observes the redirection in the prowin32.exe.config file, and loads the .2119 version instead instead, from below DLC/bin. At compile time, I believe the AVM asks the assembly for its assembly name, and this is what it writes into the r-code (I have not checked this part, but I believe this is what happens).

You might try to hack the end-user's prowin32.exe.config to redirect the .2119 versions back to .2017, but that is unsupported.

The supported solutions/workarounds are:

- deploy with 10.2B04

- compile with the end-user's version

Posted by jmls on 06-Sep-2011 09:00

Arrrgghh. I *knew* that I had been bitten by this before.

I repeat - if I have a copy of the v2017 dll in my directory, and I pointed my -assemblies to that directory, and that my assemblies.xml file stated that I wanted to use v2017, then I would expect that v2017 is compiled into my r-code.

At the very least, if progress.config is automapping the 2017 to 2092 and storing that in the r-code, then it should generate a compile warning in the compile.log, or something like that. Just, you know, so people don't get caught out

Posted by jmls on 06-Sep-2011 09:01

That's a very useful post - and makes the process understandable.

Thanks.

Posted by Garry Hall on 06-Sep-2011 09:02

RE: Supported deployment options.

I had not seen the reference to the post from Shelley. I'll defer to that for the supportability.

Posted by Garry Hall on 06-Sep-2011 09:34

To clarify the assembly loading in the context of the prowin32.exe.config file:

The prowin32.exe.config file is a .NET application configuration file, initially added to enable the AVM to locate assemblies. It is loaded when .NET is loaded, and the assembly resolution information is loaded into the CLR. When Progress updates the version of Infragistics in a service pack, we update prowin32.exe config with redirections from the previous Infragistics version to the new version. This is done so that (among other reasons) r-code compiled with the older version will automatically use the newer assemblies, instead of failing if the end-user does not have the older assemblies installed.

When the CLR is instructed to load the .2017 assembly, the CLR sees there is a redirection from .2017 to .2119, so it will look in the GAC for .2119, then probe below DLC\bin for .2119. Given that the 10.2B04 was a development environment, it might well have loaded the assembly from the GAC instead of from DLC\bin (as I had stated earlier). If these fail, then the AVM instructs the CLR to look in the -assemblies directory.

This thread is closed