Oracle.DataAccess, Version=2.112.3.0 — oracle-tech

    Forum Stats

  • 3,715,654 Users
  • 2,242,820 Discussions
  • 7,845,479 Comments

Discussions

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Oracle.DataAccess, Version=2.112.3.0

Real Blue
Real Blue Member Posts: 6
edited December 2019 in ODP.NET

Hi everybody, I need very urgent help here.

I have an application written on vb2008 using odpNet to connect to the Oracle Database. The application consist of two parts. One is a client part interacts with client the other part is a Windows Service Application.

Both parts target "AnyCPU" which means runs on both 32 and 64 bit Operating Systems.

Both parts run on the same machine which runs on virtual 64bit Win10

Client part works perfectly and connects the Oracle database with the same exact connection method which is odpNet

But service part gives "Could not load file or assembly 'Oracle.DataAccess, Version=2.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342' or one of its dependencies. An attempt was made to load a program with an incorrect format." error when it connects to the Oracle.

I have one Oracle Home, Path is correct and points to the valid Oracle Home directory.

I tried deleting Policies from GAC that didn't help also.

I searched and tried all the suggestions from Google, Stack Overflow etc.

Now I'm stuck and I need to hand this project very soon.

Any help is welcome, thanks in advance.

Answers

  • Alex Keh-Oracle
    Alex Keh-Oracle Posts: 2,751 Employee
    edited December 2019

    That error is indicative that you have either 32-bit unmanaged ODP.NET (Oracle.DataAccess) and trying to load it into a 64-bit process or vice-versa. Basically, the bitness doesn't match.

    You can do one of two things. Stay with unmanaged ODP and target x64 or x86 depending on the bitness of the ODP.NET version you bundle. Or you can move to managed ODP.NET (Oracle.ManagedDataAccess), which is fully managed and can target AnyCPU safely.

    Managed ODP.NET is available with 12c and higher. So, you will have to upgrade.

  • Real Blue
    Real Blue Member Posts: 6
    edited December 2019

    Thank you for the answer Alex.

    But I have to use Visual Studio 2008, as far as I know Managed ODP.NET is not available for VS 2008.

    I don't think there is a problem with bitness since the client part works well only the service part doesn't. Why am I so sure about it, because I use a data access class (eventually a dll) which both application use.

  • Mark Williams
    Mark Williams Member Posts: 67 Blue Ribbon
    edited December 2019

    Hi,

    As Alex mentioned this is a reported mismatch between the executing process and the DLL bitness.

    • Is the Oracle client 32-bit or 64-bit?

    • Do you have the ability to execute the following on the machine where the error is reported? This should be done from a Visual Studio command prompt that sets up the native environment correctly:

    cd <ORACLE_HOME>\bin

    link /dump /headers OraOpsXX.dll | findstr /c:"machine"

    • Replace XX with the proper version number (i.e., 11) for your environment. You should see one of the following in the output:

    machine (x64)

    machine (x86)

    • Is the service executing as a 32-bit or 64-bit process?

    It's been a long time since I have seen Visual Studio 2008 but the above should be available in some fashion — the key will be whether you have that installed on the machine that is having the issue.

    Regards,

    Mark

    Alex Keh-Oracle
  • Real Blue
    Real Blue Member Posts: 6
    edited December 2019

    Hi Mark;

    Here is the result :

    C:\app\oakuser\product\11.2.0\client_3\bin>link /dump /headers OraOps11w.dll | findstr /c:"machine"

                 14C machine (x86)

                       32 bit word machine

    For the service application there is no option to execute as 32 or 64bit

  • Real Blue
    Real Blue Member Posts: 6
    edited December 2019

    Hi again.

    When I run selecthome.bat I get the following result. Since the machine runs under Win 10 operating system and by default MS Framework 4.5 is loaded I think MS Framework 3.5 doesn't get precedence and Oracle looks for C:\app\oakuser\product\11.2.0\client_3\ODP.NET\Bin\4\ directory instead of C:\app\oakuser\product\11.2.0\client_3\ODP.NET\Bin\2.x.

    How can I force it use the specific version or disable one?

    C:\app\oakuser\product\11.2.0\client_3\bin>if exist C:\app\oakuser\product\11.2.0\client_3\ODP.NET\Bin\2.x\OraProvCfg.exe (if exist C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\CONFIG\machine.config (

    C:\app\oakuser\product\11.2.0\client_3\ODP.NET\Bin\2.x\OraProvCfg.exe /action:config /product:odp /frameworkversion:v2.0.50727 /productversion:2.112.3.0 

    C:\app\oakuser\product\11.2.0\client_3\ODP.NET\Bin\2.x\OraProvCfg.exe /action:register /product:odp /component:perfcounter /providerpath:C:\app\oakuser\product\11.2.0\client_3\ODP.NET\Bin\2.x\Oracle.DataAccess.dll

    ) )

    INFO: Configuration Section "oracle.dataaccess.client" removed!

    INFO: Oracle.DataAccess.Dll Provider Factory entry removed!

    INFO: The following section has been added.

    <section name="oracle.dataaccess.client" type="System.Data.Common.DbProviderConfigurationHandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

    INFO: The following element added under DbProviderFactories.

    <add name="Oracle Data Provider for .NET" invariant="Oracle.DataAccess.Client" description="Oracle Data Provider for .NET" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=2.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />

    INFO: Counters registered successfully in the system.

    C:\app\oakuser\product\11.2.0\client_3\bin>if exist C:\app\oakuser\product\11.2.0\client_3\ODP.NET\Bin\4\OraProvCfg.exe (if exist C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config (

    C:\app\oakuser\product\11.2.0\client_3\ODP.NET\Bin\4\OraProvCfg.exe /action:config /product:odp /frameworkversion:v4.0.30319 /productversion:4.112.3.0 

    C:\app\oakuser\product\11.2.0\client_3\ODP.NET\Bin\4\OraProvCfg.exe /action:register /product:odp /component:perfcounter /providerpath:C:\app\oakuser\product\11.2.0\client_3\ODP.NET\Bin\4\Oracle.DataAccess.dll

    ) )

    INFO: Configuration Section "oracle.dataaccess.client" removed!

    INFO: Oracle.DataAccess.Dll Provider Factory entry removed!

    INFO: The following section has been added.

    <section name="oracle.dataaccess.client" type="System.Data.Common.DbProviderConfigurationHandler, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

    INFO: The following element added under DbProviderFactories.

    <add name="Oracle Data Provider for .NET" invariant="Oracle.DataAccess.Client" description="Oracle Data Provider for .NET" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />

    INFO: Counters registered successfully in the system.

  • Mark Williams
    Mark Williams Member Posts: 67 Blue Ribbon
    edited December 2019

    Hi,

    Thanks for the information.

    The client is a 32-bit client and the service is then almost assuredly executing as a 64-bit process since you are running it on 64-bit Windows and built it as Any CPU (if I understand correctly). This is the mismatch that Alex raised.

    This is one of the aspects of the unmanaged provider that the managed provider fixes: due to the reliance on native files (i.e., OraOps11.dll in your case) it is easy to end up with a mismatch in bitness.

    I see a few immediate options:

    • Always build the client and service as 32-bit assemblies (and ensure the 32-bit Oracle client is used)

    • Always build the client and service as 64-bit assemblies (and ensure the 64-bit Oracle client is used)

    • Build both 32-bit and 64-bit versions then distribute the appropriate build to your client depending on their environment/needs

    • Continue to use Any CPU but ensure that the proper Oracle client (32-bit or 64-bit) is available to the executing assemblies

    The last option is the most difficult. If possible I would consider only building 64-bit versions of the assemblies. But I don't know what your client requirements are.

    Note that while the Oracle Developer Tools for Visual Studio require a 32-bit client (because Visual Studio is itself 32-bit and there is no 64-bit version as of today) you can still build and deploy 64-bit applications.

    In any case, the fundamental key with the unmanaged provider is that there must be a bitness match between the assemblies and the Oracle client.

    When building and deploying a service there are also other things to consider — primarily the execution environment won't likely be the same as an interactive session and permissions needed for the account under which the service executes.

    Regards,

    Mark

    Alex Keh-Oracle
  • Alex Keh-Oracle
    Alex Keh-Oracle Posts: 2,751 Employee
    edited December 2019

    You can use managed ODP.NET in VS 2008. The VS IDE has zero reliance on what is going on in the runtime. After all, this is how you can run a 64-bit .NET FW app inside a 32-bit IDE.

    A couple big reasons to choose managed ODP.NET is to avoid all the bitness issues and loading the correct dependent unmanaged DLLs.

    If you stick with unmanaged ODP.NET, there's a couple things to be aware of. Your app should directly load the Oracle.DataAccess.dll you want it to use. That means you should unGAC any other unmanaged ODP.NET versions on the machine. Earlier Oracle Client installs did GAC the assembly by default. That did ensure customers always used the latest version. However, customers now prefer to control the ODP.NET version they use. As such, make sure no ODP.NET versions are GACed on the machine you deploy.

    And make sure to check the GAC of the .NET FW runtime as there are different GACs for 2.0 and 4.0 and different GACs for x86 and x64.

    If you have multiple Oracle Clients on the same machine, you may end up with a conflict of which Oracle Client Home that your app should use. Set the DllPath in your .NET config file to point to where your app should find the correct version of the Oracle Home bin directory to use.

  • Alex Keh-Oracle
    Alex Keh-Oracle Posts: 2,751 Employee
    edited December 2019

    Mark reminded me that VS 2008 is so old that it did not support .NET4. So, I take that back. You won't be able to use managed ODP.NET because it's based on .NET 4.

  • Real Blue
    Real Blue Member Posts: 6
    edited December 2019

    Hi everybody, thank you all for replying and sharing.

    I finally managed to solve the problem. Here are the steps I did:

    • My application (both client and the server) is 32bit and compiled for AnyCPU so I don't have any 64bit application
    • The operating system that runs the application is 64bit
    • After installing OdpNet 32bit I unGACed assemblies and put Oracle.DataAccess.dll into the directory of client part, so that Oracle first looks here
    • I also installed OdpNet 64bit and didn't do anything else meaning GAC wise

    Bingo everything works now.

    There was someting with bitness but I don't think it is because of my application is 32bit or the operating system is 64bit. Somehow Oracle looks for 64bit component but doesn't really use it. Also service application directory doesn't contain Oracle.DataAccess.dll but still works. Since my application is not 64bit It really doesn't make sense. I think in the registry somehow it finds the correct dll.

    Thanks, again.

  • Mark Williams
    Mark Williams Member Posts: 67 Blue Ribbon
    edited December 2019

    I think there is some confusion around Any CPU and how it behaves at run time.

    Here's a simple exercise regarding the service portion (but applies equally to the others as well):

    • Start the Windows service as you normally would (i.e., not running from VS etc.)

    • Open Windows Task Manager

    • Click the Details tab

    • Click the Name column to sort ascending by name

    • Right-click the Name column » choose Select columns » scroll down and click the checkbox for Platform » click the OK button

    • Now find your service process in the name column and click it to highlight the row (just gives a visual reference point)

    • Scroll to the right (if needed) to confirm the value in the Platform column

    Does it say "64 bit" or "32 bit"?

    Regards,

    Mark

  • Real Blue
    Real Blue Member Posts: 6
    edited December 2019

    Hi Mark, thank you for furter help.

    Surely it says 64bit. But there are also 32bit service applications in the task list. My point is since this application is AnyCPU why did it require 64bit Oracle drivers instead of 32bit?

  • Mark Williams
    Mark Williams Member Posts: 67 Blue Ribbon
    edited December 2019
    Real Blue wrote:Hi Mark, thank you for furter help.Surely it says 64bit. But there are also 32bit service applications in the task list. My point is since this application is AnyCPU why did it require 64bit Oracle drivers instead of 32bit?

    Hi,

    The answer goes back to the beginning of the thread: Because the assembly is compiled as Any CPU and it is executing under 64-bit Windows it will execute by default as a 64-bit application. It therefore requires the 64-bit Oracle client (as this is unmanaged ODP).

    It's very easy to get into situations like this where there is a bitness mismatch when compiling as Any CPU and using the unmanaged provider (which you need to use since you are using less than .NETFX 4).

    It is possible for 32-bit and 64-bit applications (including services) to execute under 64-bit Windows which is why you see some processes that are 32-bit and (hopefully) most of the others are 64-bit in Task Manager. However, it is not possible for a 64-bit process to load a 32-bit assembly/DLL or execute under 32-bit Windows. But neither of the latter cases apply here. Just pointing it out as general information.

    When compiling as Any CPU using .NETFX less than version 4.5 in essence here is what that means:

    • When running under 32-bit Windows the process will execute as a 32-bit process

    • By default when running under 64-bit Windows the process will execute as a 64-bit process

    There's a small change with .NETFX 4.5 and higher where you can mark the assembly as "Any CPU, prefer 32-bit" but that does not apply here.

    Regards,

    Mark

Sign In or Register to comment.