How to deal with different versions of same DLL?

I recently wasted about a day while I was working on a plugin using an external library but it behaved erratically. While debugging I went down many wrong paths but finally found the reason for my trouble was quite simple:

The library I was using was referencing Newtonsoft.JSON in a recent version (9.x) and an installation of vvvv-Message was using an older version (6.x) and therefore somehow messing up my efforts to get the plugin going. Just removing Message solved the problem instantly (and made me feel stupid because I did not try my plugin on a fresh vvvv installation before :)

I was just wondering how to deal with issues like this? I guess removing the older DLL from the pack would be one solution but I guess this might introduce other problems (also it’s kind of inconvenient). Any good patterns to not run into troubles like this?

(and I bet microdee has a solution to offer that is called VPM ;)

yup you bet vpm is the new Jesus! :D
on the problem though: devvvvs could write their assembly loading bit to check stuff about the dll files because now none of the assemblies loaded with different versions present simultaneously. and it’s indeed annoying. but maybe it’s a problem outside of their scope

i think you can simply rename one of the DLLs…

I have taken great care to keep up with current versions of any dll i am using for Message, but the problem @Motzi describes is a greater one that that, and it affects all third-party dlls apart from the vvvv ones.

I had this one install, where I was including a dll from vux into my pack. After I updated dx11 libs, I could never be sure if it loads the old one (which was referenced locally in my pack), or the new one (which was in dx11-vvvv).

Rest assured, there was a warning in tty about a dll not being loaded, because it already was loaded, but this didn’t help much. Deliberate deletion of dlls seems to be the ONLY way to have this working properly (which is not something I would ask users to do).

I guess it would help already a lot, if the higher version would be preferred in general.
This would prod devs using the older version to eventually upgrade. Right now, everything can fail, if dev’s don’t update their dependencies right away, and users update all their packs just to be sure.

welcome to dependency hell everyone. as laid out in the wikipedia article this is indeed a general problem we’re facing here. not a vvvv or windows one. and not one that a package manager will solve for us.

to our understanding the solution to the problem in windows are so called strongly named assemblies. but i’m afraid we don’t have any particular experience with that. and even with strongly named assemblies it seems two problems will be left:

  • if you get a thirdparty-assembly that is not strongly-named you’re out of luck
  • types from two assemblies of different versions will not be compatible

anyway for now your best bet is to follow these rules:

  • check whether the .dll you need is in vvvv betaXY lib/core → take this
  • check whether any other pack uses the .dll you need (this can already be tricky of course)-> take this

and as velcrome already pointed out: check tty to look for errors that mention a different version of a dll has already been loaded

@joreg

so what do you say about vvvv always preferring the highest one?
you are already scanning the dependencies at startup and loading whichever comes first. would it be feasible to scan, compare versions and then loading whichever was freshest?

And then the freshest dll has lots of deprecated stuff breaking code using older versions!

Maybe picking the fresh one has the highest probability of being the best choice though.

I think the problem here is not dependency hell but how vvvv is dealing with different versions. currently if there’s 2 different versions of the same assembly none of them loads up, meaning affected plugins won’t going to work at all. suggestion here that while checking dll’s in search paths only bother and load first occurrences, we can keep an exception dialog or TTY warning that says “2 or more different versions of assembly X wanted to be loaded, preferring first occurence” and if something goes wrong after let the user deal with it. but if nothing goes wrong because of this behavior then don’t introduce a problem.

1 Like

@beyon

yeah, it is a purely heuristic strategy. good thing that nuget is using it for its default behavior.

@microdee

i think what you are describing is happening for dependencies, that have this tag in the csproj:

<SpecificVersion>True</SpecificVersion>

Dynamic compilation can utterly fail here across different vvvv versions! Also it will fail when there is a hint of a version for the dependency, because it will default SpecificVersion to True if you omit the tag.

Runtime dependency resolution for already compiled plugins will be different of course, but I’d guess that some of that mark up makes it into a manifest and forces .net to abandon loading, because versions don’t match.

not aware of this. rather you’ll find one of them randomly to work. but maybe as velcrome pointed out…

in theorie yes. we could try that. only at the moment no such mechanism is in place that checks all .dlls before any of them is loaded. we rely on .net for loading those .dlls in the order of their appearance.

also think about plugins being loaded at runtime (ie. after all packs were loaded) which could rely on an already loaded .dll but with an even higher version… it seems to me your proposal would only minimally improve the situation for packs, where it could be “easier” to just agree on one version per .dll to use per vvvv_betaXY…

How would you envision this “dll agreement” part? This is something, each user would have to do?

Lets have an example maybe. So I am using the vvvv-Message pack, which references json.net.dll 8.02. the pack itself references vvvv-Time, which hasn’t been updated ever since json.net 7.0.
Now, I install another pack, which references json.net 9.0.
Let’s assume, all of them bring their dependency dll in the /core directory, so each pack can work without any other pack installed.

Right now, the only solution seems to be to remove either all other packs, or take the pain and scan all of them for the dll and manually decide for the newest one. If you don’t do that, it might even work, but it might not work the next time, when assembly load order is different.

Also, I have seen that you have an (experimental) way to pack a pack within a nuget (probably geared for vl). Is this something that you will promote and push, even for vvvv? Because that might settle quite some issues here…

for example in case of VAudio it won’t going to work with alpha’s because of the different version of naudio included both in VAudio and in vl.core.experimental (if I remember well). neither vaudio nor vl going to work in that case (nodes missing according to vvvv) delete one of them the other starts to work. we discussed it with tonfilm already in another forum post.

@velcrome: the theory (which will hardly be feasable in practice) was: we agree that betaXY uses json.net 9.0 and then every contributor builds his stuff against that and we can all be sure that all packages built for betaXY work together in harmony.

have you looked into loading eg. the json.net.dll with a strong name (see above)? you could check if that already would make a difference.

regarding nugets the info is here: https://vvvv.org/blog/vl-autumn-update#nugets
so yes, this is already the standard way for vl. every library in vl is neatly packaged in a nuget. but note that, as mentioned above, this will not automatically solve dependency hell.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.