Oracle Data Access Components – Development Installation Tips

aka ODAC

start here for latest downloads

Oracle Provider for OLE DB

  • I initially found a free generic database object browser tool called Oracle Maestro
    • i actually wound up landing on a much better tool, linked below, but getting Maestro to work walked me through some troubleshooting which would come up for anything requiring OLEDB connectivity
    • Maestro happened to be 32bit only and as usual, the bitness of our runtime is a fun factor…
  • the need for an OLEDB connection string prompted my handy trick of creating a “test.udl” file and then double clicking it to get into a helpful OLD DB Config Wizard UI… once you’ve configured a connection, just notepad that UDL file to copy/paste the connection string, nice!
  • i didn’t have any Oracle providers loaded on my naked win10 instance so i hit the download site above and initially loaded the 64-bit ODAC 12.2c Release 1 (12.2.0.1.0) for Windows x64
  • back to test.udl… now the Oracle provider was listed but immediately upon hitting “next” i got “Provider is no longer available. Ensure that the provider is installed properly.“…
    • using SysInternals ProcMon i saw it seemed to be failing to find oci.dll … started smelling like a binaries path issue… eventually i flip flopped the order of $\oraclehome64\ & $\oraclehome64\bin in my system path and that went away… perhaps also simply because of a reboot
  • i had a connection string now…
  • however, firing up Oracle Maestro, the Oracle Provider was not listed… that’s when i remembered the deal with 32bit and 64bit OLEDB stacks…
  • now loaded “32-bit ODAC 12.2c Release 1 and Oracle Developer Tools for Visual Studio (12.2.0.1.0)”
  • and back to test.udl, here’s where i use another trick… launching c:\windows\SysWow64\cmd.exe and then start test.udl from there makes sure i’m launching the 32bit OLEDB config UI which happens to be via a C:\Windows\SysWOW64\rundll32.exe command line vs C:\Windows\System32\rundll32.exe
  • here is an example “TNS-less” DataSource for OLE DB based connections: (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = ABC.org)(PORT = 1521)) ) (CONNECT_DATA = (SID = XYZ) ) )

.Net Core Projects and “ODP.NET Managed Driver” aka ManagedDataAccess

  • Just reference through Nuget however it is not .Net Core Runtime compatible yet (supposedly .Net Core 2.0 savvy version coming end of 2017)…
  • Must run on top of traditional .Net Framework until Oracle releases their .Net Core 2.0 compatible update
  • Under VS2017 the ASP.Net Core MVC project template is friendly to this mix (see next screenshot below)
    • which also gives us the necessary clue to spin up other less flexible Core project templates and manually edit the csproj to net461

nPoco requiring DbProviderFactory vs direct instantiation UNDER .Net Core

  • typical error message: System.ArgumentException: ‘Unable to find the requested .Net Framework Data Provider. It may not be installed.’
  • the gist is the current Core incompatible ODP.Net is expecting to configure our project’s app.config or web.config …
  • yet as we know, Core has shifted to appsettings.json, no .config file present… which leads me to next heading…
  • yet, in this case, there’s simply a 3rd parameter where we can pass the factory like so:
    new NPoco.Database(ConnectionString, NPoco.DatabaseType.OracleManaged, Oracle.ManagedDataAccess.Client.OracleClientFactory.Instance)

Tip – Generally fixing .Net Framework based Nuget lib’s configuration under .Net Core projects

  1. spin up a quick traditional framework console app
  2. nuget reference the culprit Nuget lib as usual (“Oracle.ManagedDataAccess” in this case)
  3. copy the pertinent sections in the resulting app.config to your C:\Windows\Microsoft.Net\Framework(64)\v4.0.30319\Config\machine.config
    • this stack-o clued me in to remember there is both a Framework and Framework64 folder…
    • i’ve noticed, in my environment anyway, an ASP.Net MVC Core site launches under a 32bit process requiring the settings to be present in \Framework
    • while a .Net Core Console app will launch a 64bit process requiring the \Framework64 settings

machine.config entries i wound up editing in as of current version

<configuration>
  <configSections>
    <section name="oracle.manageddataaccess.client"
      type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342"/>

  ...

  <system.data>
    <DbProviderFactories>
      <remove invariant="Oracle.ManagedDataAccess.Client"/>
      <add name="ODP.NET, Managed Driver" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver"
          type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342"/>
    </DbProviderFactories>
  </system.data>

</configuration>

snapshot of the nuget install

snapshot of the DbProviderFactory error

3rd Party Tools

Oracle Forms 11g Development Installation Tips

Yeah I actually said Oracle Forms, that product from the 90’s… as one might guess, i happen to be on a legacy conversion project at work…
There’s some rough edges getting these old bits to install and run that i wanted to capture…

Background

  • my project is tied to the Oracle Forms v11g stack… the latest 11.x version at this time appears to be 11.1.2.2.0
  • we’re using the web servlet stuff which runs our forms as java applets… it’s actually a pretty slick rich client arrangement for the bygone era it heralds from
  • the primary breakthrough i made was getting it all installed once and then doing “xcopy” deploy of the main “Oracle Home” folder (c:\oracle\middleware) to my other team members’ machines… plus the appropriate registry branch (e.g. HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OH1949191890)

Java dependency

  • JDK required – JRE’s not enough
  • JDK 1.6.0u35 – through painful trial and error i’ve settled on this fairly dated release… i’ve seen various components in this whole stack run on more recent JDK’s but subsequent obscure runtime errors beat me into submission

both 32 & 64bit required

  • we are running on Win10 x64 naturally preferring to install 64bit executables…
  • thereby running the 64bit Forms Builder installation which requires 64bit JDK…
  • however the servlet web site generates 32bit java <code> tag references (i’m kinda thinking IE was 32bit only at the time) so we also need the 32bit JDK installed

Java Applet troubleshooting tips:

  • be aware that Control Panel > Java will most likely only show you the 64 bit control panel…
  • you’ll need to specifically launch the 32bit panel via C:\Program Files (x86)\Java\jdk1.6.0_35\jre\bin\javacpl.exe
  • from there you’ll want to enable the Advanced > Java Console > Show Console, to get some visibility on any exceptions firing
  • and very crucial tip here… Advanced > Default Java for browsers > Microsoft Internet Explorer is always greyed out but you can select that node and hit space bar to select it (nuts)
    • its also probably helpful to go back to the 64bit javacpl and uncheck it there

Browser dependency

  • IE (v11 works) is the only browser that will properly launch the 32bit java applet for us on Windows 10 x64 (not Chrome, not Firefox, not Edge)
  • IE11 can actually run in 64bit or 32bit mode depending on what each page’s elements require and due to the 32bit java tags mentioned above, it spawns into a 32bit IExplore.exe process

Main Installation Steps

  1. stop your virus checker’s active file scan – we’re on McAfee enterprise and everybody is pretty spooked that it interferes with these ancient installs and i had enough problems to go ahead and rule it out
  2. WebLogic Server v1.0.3.6 hard dependency
    • i loosely understand weblogic as the web server backend, “servlets”, which deliver the pages and java applets
    • as mentioned, we’re targeting the 11g/11.x stack which drives this 1.0.3.6 version requirement… seriously, trust me, save yourself the trouble, any other version is not going to work with the 11.x Oracle Forms stack which comes next
    • see download links at the bottom of this page
    • CRUCIAL – make sure to get the “Generic” jar – specifically wls1036_generic.jar
    • CRUCIAL – launch wls1036_generic.jar specifically via the golden JDK above under ELEVATED aka Admin command line like so
      • C:\Program Files\Java\jdk1.6.0_35\bin -jar wls1036_generic.jar
    • DO NOT just double click the .jar to launch, that will typically launch via JRE WHICH WILL ACTUALLY INSTALL WITHOUT ERROR AND THEN BITE YOU when it comes to the Oracle Forms piece… i know, nuts!
    • we went with the default c:\oracle “home” path… which wound up creating a single c:\oracle\middleware folder
  3. Oracle Forms 11.x (v11.1.2.0 is current latest)
    • the x64 zips worked for us…
    • download & extract those zips and fire up the Disk1\setup.exe ELEVATED
    • the prompts are pretty straightforward…
      • and one big important choice is to choose “Install Software – Do Not Configure”… we’ll do the configure step next
      • we stuck with the default “Oracle_FRHome1” path
      • skip security updates (that ship has long since sailed 😉
    • once the install finishes then fire up c:\oracle\middleware\Oracle_FRHome1\bin\config.bat ELEVATED
      • select “configure for development” vs deployment
      • provide the previous weblogic and oracle home paths…
      • we just went with FormInstance1 for the instance path
      • “for development only”, didn’t select the reports bits
      • auto port configuration = yes
  4. Lastly were specific environmental configs, YMMV
    • copy our default.env file to c:\oracle\middleware\user_projects\domains\FORMDomain\config\fmwconfig\servers\AdminServer\applications\formsapp_11.1.2\config
    • copy our formsweb.cfg => c:\oracle\middleware\user_projects\domains\FORMDomain\config\fmwconfig\servers\AdminServer\applications\formsapp_11.1.2\config
    • copy our tnsnames.ora and sqlnet.ora => c:\oracle\middleware\FORMInstance\config
    • copy jacob.jar => c:\oracle\middleware\Oracle_FRHome1\forms\java
    • copy jacob.dll => c:\oracle\middleware\Oracle_FRHome1\forms\webutil (NOT down to either \win32|\win64)
    • CRUCIAL – update registry HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OH1949191890\FORMS_PATH to include your forms “.fmb, .mmb, etc” file paths… we had separate folders for images, forms, libs & menus files to be included there
      • this “KEY_OH1949191890” path is probably different for each installation

Easy *Native* Windows Self Extracting EXE Builder (SFX)

This is an oldie but goody… the gist is that even latest Windows 10 still ships with working IExpress.exe which is a self extracting exe builder! Who knew.

In my case, very handy for bundling a batch file and it’s dependencies into a single exe for a buddy.

For the record, I started out with 7zip’s SFX facility and eventually got it working but it’s a bit more clunky… besides the steps required to build an auto launch exe, you’ll get a mildly undesirable “Program Compatibility Assistant” “This program might not have installed correctly” warning… the IExpress generated exe doesn’t seem to have this issue.

Launching IExpress.exe without any args will present the wizard which will walk you through building a “SED” config file with several commonly desired “setup.exe” options like user confirmation prompt, etc… importantly, this includes specifying a batch file you wish to be launched after extract.

Handy batch for recreating exe whenever you update your script:

::start sets appropriate working directory
::especially crucial when launched as admin (which normally defaults to c:\windows\system32)
::and allows us to use relative file references in the SED config file so that launching from any path works (including UNC)

start "Title" /d"%~dp0" iexpress /n Project.sed

Tips

  • The program to be launched can indeed be a .BAT/.CMD
  • The IExpress SED wizard will hard code paths, just edit afterwards and remove to be relative. It works.
  • This would of course work for PowerShell or any other script that can be launched via its runner, either bundled in the EXE or native, e.g. ScriptCS

VS Code, Typescript – Bare Metal New Project

i’m basically following this guide, while humbly attempting to trim down to bare necessity and re-align configs with crucial bits that’ve shifted since then… and likely to continue shifting 😐

  1. install Node… there’s many ways but their setup.exe is handy… this includes npm
  2. from cmd.exe: npm install -g typescript (-g means globally vs project specific)
  3. install VS Code via setup.exe
  4. launch VS Code… commands inside VS Code designated as “vsc>” from here-on
  5. vsc> File > Open > New Folder > “projectFolder” > then Open that folder
  6. vsc> F1 > type “task” > “Configure Task Runner” > Enter > “TypeScript – Watch Mode” > Enter
    1. this will create a crucial tasks.json file with working default settings…
    2. -AND- that “watch mode” choice means the moment you save any .ts file, the IDE will automatically regen the corresponding .js files… which plays into live edit and continue style debugging
  7. vsc> File > New File > populate with the following json block and save as tsconfig.json … this directs vscode to “transpile” .ts script to standard .js for us
    {
        "compilerOptions": {
            "target": "es5", 
            "outDir": "out/",
            "sourceMap": true
        }    
    }
  1. vsc> File > New File > throw in something simple like console.log("Hello World!"); and save as app.ts
  2. vsc> build aka compile via CTRL+SHIFT+B… after a few pregnant seconds, this will gen some stuff in the out folder that we specified in above tsconfig.json
  3. vsc> CTRL+SHIFT+D to get into Debug panel > click the gear icon which creates and opens default launch.json which should have working defaults going by what we’ve done previously
  4. crucial and subtle, navigate back to the app.ts file as the active tab you wish to run/debug (this corresponds with the relative reference, "program": "${file}", in launch.json)
  5. now we should be able to simply hit F5 to run/debug from here-on as we’d normally expect… F9 to set breakpoints, etc.

hopefully you’re off to the races and you can bootstrap yourself further by googling

i am a bit “ashamed” this is still so obtuse

Syncfusion Xamarin.Forms SfDataGrid – Binding to List<Dictionary<,>>

corresponding syncfusion forums post

Binding to Collection<Dictionary<,>> can be accomplished but doesn’t appear to be well documented… this WPF SfDataGrid doc gave the clue.

The basic trick is to set the SfDataGrid’s column.MappingName = “Fields[FieldName]”;
where Fields is a Dictionary property on your DictionaryWrapper class.

I couldn’t get List<Dictionary<string, object>> working directly without the wrapper class “hiding” the dictionary from what I think is an SfDataGrid bug. The app crash exception call stack ultimately winds up on an invalid Linq related get_Item() call.

Below is sample working code including “SimpleTable” wrapper for List and Newtonsoft type converter for deserializing Json “table” directly into this datastructure… this facilitates delivery of tabular resultsets from web api’s… see my SqlClientHelpers.ToJson method as one implementation that works succinctly within Azure Functions for example.

FYI, I believe there is also a bug with SfDataGrid column sorting logic when bound to this kind of Dictionary, a non-fatal exception fires. I worked around by implementing grid.SortColumnsChanging.

Sample Deserialize call:

var data = "[{\"Source\":\"Web\",\"Batch Id\":1}, {\"Source\":\"Manual\",\"Batch Id\":2}]";
var table = JsonConvert.DeserializeObject<SimpleTable>(data);

Binding sample with crucial MappingName syntax:

grid.ItemsSource = table;
grid.Columns.Add(new GridTextColumn()
{
  HeaderText = "Source",
  MappingName = "Vals[Source]" // **** HERE'S THE KICKER ****
});

SimpleTable.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace DataHelpers
{
  [JsonConverter(typeof(DictRow_DictDeserializer))]
  public class DictRow
  {
    public Dictionary<string, object> Vals { get; set; }
    public DictRow(Dictionary<string, object> dict) { Vals = dict; }
  }

  public class SimpleTable : List<DictRow>
  {
    public SimpleTable(IEnumerable<DictRow> list) : base(list) { }
  }

  public class DictRow_DictDeserializer : JsonConverter
  {
    public override bool CanRead => true;
    public override bool CanWrite => false;
    public override bool CanConvert(Type objectType) => objectType == typeof(Dictionary<string, object>);

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
      return new DictRow(serializer.Deserialize<Dictionary<string, object>>(reader));
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
      throw new NotSupportedException();
    }
  }
}

Android Emulator Nuggets

Installing Google Play

  • This worked very nicely minimally for Android v7.1.1 “with Google APIs”…
  • Need to launch emulator.exe with -writable-system -selinux permissive args
  • grab the version of OpenGapps you want
  • Basically follow this guide but stop at “Restarting and Creating another Image”
    • Then adb root & adb remount
    • and I found that I just needed to adb shell mkdir /system/priv-app/Phonesky & adb push Phonesky.apk /system/priv-app/Phonesky not the other priv-apps
  • and I also didn’t have to create a new image vs simply rebooting

Root

one time

  • Grab SuperSU Recovery Download and extract “su”
  • adb root & adb remount
  • adb push su /system/xbin/
  • adb shell chmod a+x /system/xbin/su

create .cmd script for each launch

  • {path}\emulator.exe -avd Nexus_9_API_25 -writable-system -selinux permissive
  • adb wait-for-device & adb root & adb remount & adb shell "su -ad &"
    • -ad stands for auto-daemon and just sounds cool…
    • i haven’t seen anybody set this up to where android automatically launches the su daemon)
  • then just go install SuperSU from the Play Store
    • DO NOT allow it to upgrade the su binary upon prompting… that always hung my virtual device after reboot
  • and lastly fire up a Root Checker from Play Store to make sure

Clipboard integration

  • Android Studio (as of v2.3) directly supports Windows <=> Emulator cliboard integration (ref)
  • ADB shell input text "sample text" is pretty handy too

Handy Links

  • Android Studio download… main tools:
    • SDK Manage
    • AVD Manager
    • Device Monitor – event log and GUI file explorer
  • Google Play APK Downloader
  • ChainFire’s “How To SU”
  • Windows AVD Folder where the runnable virtual machines sit: %UserProfile%.android\avd
    • HOWEVER Upon running Android Studio’s vs Visual Studio’s version of emulator.exe will manipulate the %UserProfile%.android\avd\hardware-qemu.ini to point the .img file paths to their folders
  • Android Studio puts everything here: %AppData%..\Local\Android\SDK
  • Visual Studio puts everything here: C:\Program Files (x86)\Android\android-sdk
    • \platform-tools\adb.exe
    • \tools\emulator.exe
    • \system-images\android-25\google_apis\x86_64\system.img, etc.
  • AStudio emulator.exe runs better NOT elevated
  • VStudio emulator.exe runs better ELEVATED
  • AStudio emulator.exe v2.5.2 looks like it creates “copy on write” system.img.qcow2 files instead of modifying system.img directly which means you can save that qcow2 file as backup or erase it to rollback to clean baseline
  • VStudio emulator.exe v2.5.5 looks like it modifies system.img directly
  • qemu-img.exe info file.qcow2 will show you what base .img it’s linked to (download qemu bundle)
  • Install Intel HAXM directly if SDK Manager is no cooperating

My full fidelity emulator launch script

(special TCC/LE batch syntax)

@echo off
SETLOCAL 

::call tk qemu-system-x86_64
start "Android Emulator" /inv /pgm "C:\Users\beej1\AppData\Local\Android\sdk\emulator\emulator.exe" -avd Nexus_9_API_25 -writable-system -selinux permissive
adb wait-for-device
adb root
adb remount
adb shell "su -ad &"

:pasteloop

echos Press any key when ready... to paste current clipboard to android^r
pause

set clipline=0
do forever
  set cliptxt=%@clip[%clipline%]%
  if "%cliptxt%" EQ "**EOC**" LEAVE
  adb shell input text '%cliptxt%'
  set clipline=%@inc[%clipline%]%
enddo 
goto pasteloop

[SOLVED] Xamarin Forms iOS build error: An inconsistency between the local app and the remote build has been detected for _____. Please rebuild the application and try again.

image

there’s tons of hits on this but for me it seems to somehow be a “corrupt” solution file…

solution == new solution ; )

i spun up a new xam cross platform project solution and simply readded my existing PCL and iOS projects from the broken solution and it built and deployed to simulator just fine

keeping the old solution around for a rainy day diff

notables:

  • i am running Visual Studio 2017 RTM (15.0.0-RTW+26228.4) but i’m pretty sure i ran into this on VS2015 a while back as well.
  • tried upgrading all Windows and Mac bits to latest Xamarin Alpha
  • tried upgrading to the latest XCode (8.2.1)
  • walked throught the majority of this connection troubleshooting opus at the ready (gee Xam dudes, problems here much?)…
  • tried Clearing the Mac Build cache
  • enabled verbose logs (c:\> devenv /log)
  • there’s just nothing logged out to any of the Mac or Windows log folders for that error
  • i had another solution lying around that i created about a month ago when i ran into this error (same projects)… i just loaded it up and got the “inconsistency” error on the first run attempt, but then it actually went thru and launched the simulator upon second try – go figure