When you call a J# DLL from .NET 4.0 (or later) code, you will get an error that vjsnativ.dll could not be located. The work-around to date has been to copy vjsnativ.dll to the directory of the primary application calling the code. For an app this is workable althogh a bit if a pain. But for web apps this can be very problematic as you're talking the underlying web server.
It turns out there's a much easier approach. The following code needs to be called in your C# code before instantiating any classes or calling any code in a J# DLL. After you call this, you can then call all of your J# code. The trick is simple – you load the library explicitly and then Windows already knows its location.
Simple example:
using System;
using System.IO;
using System.Runtime.InteropServices;
using net.windward.api.csharp;
namespace TestNet40
{
class Program
{
[DllImport("kernel32", SetLastError = true)]
static extern IntPtr LoadLibrary(string lpFileName);
static void Main(string[] args)
{
if (Environment.Version.Major >= 4)
{
string folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), @"..\Microsoft.NET\Framework\v2.0.50727");
folder = Path.GetFullPath(folder);
LoadLibrary(Path.Combine(folder, "vjsnativ.dll"));
}
// now call J# code
Report.Init();
Console.Out.WriteLine("success!");
}
}
}
What we have done for Windward Reports (our kick-ass reporting & docgen system - and can be called directly from J# – check it out) is place this code in the static constructor of our main C# wrapper class. That class is how our customers access our J# code, so it is always called before any calls are passed down to the J# DLL. By placing this inside our wrapper, users don't even need to include this code snippet. But if you provide your J# code directly, then your users will need to explicitly call this code before calling any of the J# code.


Excellent. Really appreciate your knowledge.
Posted by: YK | 03/14/2011 at 12:26 AM
Nice find! This is much more flexible than the inclusion of the DLL in the project.
Posted by: Cole Chamberlain | 05/26/2011 at 12:41 PM
This is a perfect solution!
This is finally a solution to the following messages:
"The type initializer for 'java.lang.System' threw an exception."
InnerException: "Unable to load DLL 'vjsnativ': The specified module could not be found."
(I tried copying DLL's, using 64bit and 32bit J# DLL's, ... For one NT Service I could call the J# DLL's, for the other one NOT, on the same W2008R2-64bit server :-))
Anyway, here's the VB code for it (For my situation I just put it in my constructor):
Don't forget: You really have to install the Visual J# Redistributable Package.
Greetz,
Jim Adorno
Posted by: Jim Adorno | 09/26/2011 at 06:21 AM
As for Cole, copying the file didn't work for me either, but your code (adapted for my program) finally helped!
Thank you so much!
Posted by: grettyr | 11/07/2011 at 04:39 AM
Thank you very much for sharing your solution. In my 32bit WebApp this works fine. Unfortunately I have to use a 64bit IIS process. In my case your solution doesn't work.
Is there a way to run J# in a .NET 4.0 64bit worker process?
Greetings
Posted by: Karim El Jed | 11/07/2011 at 07:33 AM
Just found the simple answer by myself... :)
string folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), @"..\Microsoft.NET\Framework64\v2.0.50727");
Posted by: Karim El Jed | 11/07/2011 at 07:43 AM