[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 14810
  • Last Modified:

The provider is not compatible with the version of Oracle client

Hello there,

I realise this question and it's variants have been asked before and I've looked through them but am asking this particularly because it's quite urgent and also the answers didn't seem to quite fit.

I have a set of dll's which contain functions to load/extract data from oracle. Due to a whole load of reasons, I'm having to dynamically call them from a .net exe using Reflection.

Now, when I try running the dll through MSDev, it connects to Oracle fine but when I try to invoke it using reflection from the exe (I made sure I referenced the same dll (from debug path) in my exe for test purposes) it throws a provider not compatible error.

In the dll project, I bundle the Oracle.DataAccess.dll along with other necessary dlls (OraOps11w.dll,oci.dll?) with the setup so they are all in the same path.

For some reason I get this error during dynamic invocation. some of my team members seem to get it even otherwise on their machines. Don't understand why it should mismatch dll's when all of the necessary one's are avaialble in the same path.

Any ideas please? (will reply tomorrow)

Thanks,
Leo
System.TypeInitializationException was unhandled
  Message="The type initializer for 'Oracle.DataAccess.Client.OracleConnection' threw an exception."
  Source="Oracle.DataAccess"
  TypeName="Oracle.DataAccess.Client.OracleConnection"
  StackTrace:
       at Oracle.DataAccess.Client.OracleConnection.Dispose(Boolean disposing)
       at System.ComponentModel.Component.Finalize()
  InnerException: Oracle.DataAccess.Client.OracleException
       Message="The provider is not compatible with the version of Oracle client"
       Source="Oracle Data Provider for .NET"
       ErrorCode=-2147467259
       DataSource=""
       Number=-11
       Procedure=""
       StackTrace:
            at Oracle.DataAccess.Client.OracleInit.Initialize()
            at Oracle.DataAccess.Client.OracleConnection..cctor()
       InnerException:

Open in new window

0
lm78
Asked:
lm78
  • 5
  • 4
  • 3
2 Solutions
 
slightwv (䄆 Netminder) Commented:
Oracle clients cannot just be 'copied'.  They need to be installed.  Just because you have certain DLLs included, Oracle makes calls to others.

With ODP.Net, the verion compiled with the app needs to match the version installed on the apps machine EXACTLY.  to date, I have yet to figure out how to even use minor version differences.
0
 
slightwv (䄆 Netminder) Commented:
>> "because it's quite urgent"  and "will reply tomorrow"

These two statements really don't seem to go together but it's your question...
0
 
lm78Author Commented:
Well, i installed odp.net on my machine. To make sure the install would work on a machine with differing versions, I put the necessary dll's as dependencies in the setup project. I reference the dll (one I've put in the dependency folder) explicitly in the project.

Would that not work? How can I check which version it's trying to load?

Haha - yes, urgent as i've struggled with this for a few days now and have to get it done in the next couple of days or so (but only so much you can do on one day!)

0
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 
mrjoltcolaCommented:
Which version specifically, and also is it 32-bit or 64-bit ODP.NET? 64-bit OS?

How are you building your .NET app, x86, x64 or Any CPU?
0
 
slightwv (䄆 Netminder) Commented:
>>To make sure the install would work on a machine with differing versions, I put the necessary dll's as dependencies in the setup project

Unfortunately Oracle Clients don't really work that way.  You just cannot copy a few DLLs around and get everything to work.  You can do this with some of the Instant Client installs but I've not seen this with the ODAC.

Best case is the ODAC with Xcopy Deployment but this still has a setup script you need to run to set up some Oracle environmental things.

>> I reference the dll (one I've put in the dependency folder) explicitly in the project.

But those DLLs will likely reference DLLs in the Oracle client install directory.

>>How can I check which version it's trying to load?

In ODP.Net, find the OracleDataaccesss.dll, right click, properties then version.  The one in the apps bin directory, needs to match the one for the full Oracle install EXACTLY.
0
 
lm78Author Commented:
Okay, I tried referencing the dll directly from the home directory instead of from the dependencies folder and calling it from dynamic invocation worked!

That's a great step forward - (still can't understand why it would work when I run it from Dev Env directly but not when I call the very same project from a client ).

Have the following questions though please-

1. .NET Setup Packaging - I initially put the necessary dll's in a dependency folder in the .NET setup project.  How do I actually package the OracleDataAccess.dll if I'm supposed to be accessing it from the home directory or wherever?

2. On the Oracle side - what precautuions do I need to take in view of multiple homes? How do I know which version of ODP.Net it's going to use and so on? Does it pick it up from the ORACLE_HOME path? The documentation seems to say it looks at the DllPath - but there is a dllpath for each version of odp.net installed.

For eg., I've got 3 ODP.Net keys in the registry - 1.111.7, 2.111.7 and 2.111.7.20. Not sure how it determines which one to use.

@mrjoltcola: it's 32 bit Windows system and 32 bit odp.net . I do a build for AnyCPU.

Sorry if I'm asking stupid questions, but am slighty confused by the requirements in oracle, not sure I'm getting my head around it properly.

Thanks,
Leo
0
 
slightwv (䄆 Netminder) Commented:
>>How do I actually package the OracleDataAccess.dll if I'm supposed to be accessing it from the home directory or wherever?

I've been trying to tell you this:  You cannot.  

The Oracle ODAC needs 'installed'.  I suppose you could figure out everything the setup command file does and port it all into the .Net packager but that would likely be a lot of work.

>>How do I know which version of ODP.Net it's going to use and so on? Does it pick it up from the ORACLE_HOME path?

To be perfectly honest:  I have no idea about the 100% proof positive way.  There are likely several ways Oracle tries to find toe correct binaries it needs.  ORACLE_HOME is an important one.  PATH is another.  In Windows the Registry has a major role as well.

>>Not sure how it determines which one to use.

I believe the app knows what version was referenced at compile time.  It will look for that specific version.  Remember, I've said a few times, the version must match exactly.
0
 
lm78Author Commented:
Thanks, I get that - i've just had a few failures on one machine now - I tried installing the exact version of ODP.net dll's that I referenced originally in the c# project but it still failed with the same error.
There were other clients installed on that machine.  Makes me wonder how it was checking - I included everything in the PATH. Set the ORACLE_HOME to 11g path (for the new install).

All that was done but still failed.
The only thing I can think of as a possible cause for the failure is this-
The client application (Excel VBA) for some reason has been set up to use Oracle 9.x OLE DB driver and any other install after that usually breaks it - the installation of 11g ODAC broke the application and I had to install ole db 9 again after which the VBA application worked. The VBA calls the c# dll framework application which again returned the same error.

Which is why I was asking so much about where it takes the version/home etc from. This is the only thing I can think of which could have caused the C# framework to fail even after installing the correct dll version.

(Sorry if this is unnecessarily confusing - just thought I'd put forward all my thoughts on this)
0
 
slightwv (䄆 Netminder) Commented:
No need to apologize.  The whole ODAC thing is pretty confusing to me as well.  There are parts I still don't understand, like what you referenced.

I just know the versions must match.  I've not tried to install OleDB drivers in a different home on the same machine but I could believe it would mess things up.

The closest I can get is two versions of the ODP.Net on the same machine.  Somehow the different .Net apps can find their correct version.  Never had to dig into the 'how'.

If you have a support contract with Oracle, this might be a great question for support.
0
 
mrjoltcolaCommented:
>>How do I know which version of ODP.Net it's going to use and so on?

This is based on the specific assembly you reference in your .NET app during compile. .NET assembly versioning supports loading of specific versions of an assembly.

But the .NET assembly portion of the ODAC needs to be able to find the specific version of unmanaged dlls (OCI) that is compatible with the managed assembly. This means PATH should reference the right OCI client first.

If all your apps on the same computer use the same clients, then it is pretty simple, but if you have multiple apps on a server, often they may need different versions; that config is supported.

In your app.config, you can config each app with DllPath config param of the oracle.dataaccess.client

http://download.oracle.com/docs/html/E10927_01/InstallODP.htm

From the docs..
<oracle.dataaccess.client>
    <add key="DllPath"            value="C:\oracle\bin"/>
    <add key="FetchSize"          value="65536"/>
    <add key="StatementCacheSize" value="10"/>
    <add key="TraceFileName"      value="c:\odpnet1.trc"/>
    <add key="TraceLevel"         value="63"/>
    <add key="TraceOption"        value="1"/>
  </oracle.dataaccess.client>

Open in new window


It is not required to compile an app with a specific version of ODP.NET if you load it all dynamically via reflection.

But if you use it via a compile time reference, the Oracle docs say the versions must match exactly. If you have an app built with an older version of odp.net, it can use a newer version via use of the policy files to redirect. That is also covered in the doc above.

Rather than putting ALL Oracle homes in the PATH, I'd setup separate user environments for each app (except in case of ASP.NET where that isn't possible, you need to use the app specific config above).
0
 
mrjoltcolaCommented:
I personally use DevArt's dotConnect for Oracle, as I got tired of all of the ODP.NET versioning annoyance.

We are told that later this year, Oracle may be releasing a complete managed ODP.NET (full thin driver) equivalent to JDBC thin driver. Finally .NET will be on the same playing field as Java when it comes to deploying pure managed apps.

https://apex.oracle.com/pls/apex/f?p=18357:46:88988165448659
0
 
lm78Author Commented:
Wow. Thanks mrjoltcola and slightwv! Got the app working finally.

Strangely though, after doing all that, removed the references you had cited above from the app.config file and it continued to work!! Seriously....

@mrjoltcola: Could you tell me also how to load the OracleDataAccess dll via reflection please? Will save me an hour or so of reading!

Thanks again!
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

  • 5
  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now