jni4net failed to load DLLs in Java app

3k Views Asked by At

I'm trying to modify the jni4net sample code MyCSharpDemoCalc, and make the sample as a bridge between a .Net DLL and the Java layer. Here is the C# code:

using System;
using Dynamsoft.DotNet.TWAIN;

namespace MyCSharpDemoCalc
{
    public interface ICalc
    {
        int MySuperSmartFunctionIDontHaveInJava(string question);
        bool IsShowUI();
    }

    public class DemoCalc : ICalc
    {
        private readonly Random r = new Random();
        private DynamicDotNetTwain dynamicDotNetTwain;

        public DemoCalc()
        {
            dynamicDotNetTwain = new Dynamsoft.DotNet.TWAIN.DynamicDotNetTwain();
        }

        public int MySuperSmartFunctionIDontHaveInJava(string question)
        {

            if (question == "Answer to the Ultimate Question of Life, the Universe, and Everything")
            {
                return 42;
            }
            return r.Next();
        }

        public bool IsShowUI()
        {
            return dynamicDotNetTwain.IfShowUI;
        }
    }
}

In order to build it successfully, I added the following references:

  • System.Windows.Forms
  • DynamicDotNetTWAIN

Then typed in the command

proxygen.exe MyCSharpDemoCalc.dll -wd work

to generate MyCSharpDemoCalc.j4n.jarand MyCSharpDemoCalc.j4n.dll.

Now, I can import DynamicDotNetTWAIN.dll, MyCSharpDemoCalc.j4n.dll, jni4net.n.w64.v20-0.8.6.0.dll, jni4net.n-0.8.6.0.dll, jni4net.j-0.8.6.0.jar and MyCSharpDemoCalc.j4n.jar to Java project.

Java code:

import net.sf.jni4net.Bridge;

import java.io.IOException;

import mycsharpdemocalc.DemoCalc;
import mycsharpdemocalc.ICalc;

public class Program {
    public static void main(String arsg[]) throws IOException {
        Bridge.setClrVersion("v20");
        Bridge.init();
        Bridge.LoadAndRegisterAssemblyFrom(new java.io.File("DynamicDotNetTWAIN.dll"));
        Bridge.LoadAndRegisterAssemblyFrom(new java.io.File("MyCSharpDemoCalc.j4n.dll")); // crashed

        ICalc calc = new DemoCalc();
        final int result = calc.MySuperSmartFunctionIDontHaveInJava("Answer to the Ultimate Question of Life, the Universe, and Everything");

        System.out.printf("Answer to the Ultimate Question is : " + result);
        System.out.printf("If show UI : " + calc.IsShowUI());
    }
}

When I tried to run the application, it crashed at

Bridge.LoadAndRegisterAssemblyFrom(new java.io.File("MyCSharpDemoCalc.j4n.dll"));

Exception in thread "main" System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
   at System.Reflection.Module._GetTypesInternal(StackCrawlMark& stackMark)
   at System.Reflection.Assembly.GetTypes()
   at net.sf.jni4net.utils.Registry.RegisterAssembly(Assembly assembly, Boolean bindJVM, ClassLoader classLoader)
   at net.sf.jni4net.Bridge.RegisterAssembly(Assembly assembly, ClassLoader classLoader)
   at net.sf.jni4net.Bridge.LoadAndRegisterAssemblyFromClassLoader(File assemblyFile, ClassLoader classLoader)
   at net.sf.jni4net.Bridge.LoadAndRegisterAssemblyFrom(File assemblyFile)
   at net.sf.jni4net.__Bridge.LoadAndRegisterAssemblyFrom3(IntPtr __envp, JniLocalHandle __class, JniLocalHandle assemblyFile)
    at net.sf.jni4net.Bridge.LoadAndRegisterAssemblyFrom(Native Method)
    at com.main.Program.main(Program.java:68)

How can I fix it? Thanks!

1

There are 1 best solutions below

0
On

The JNI4NET will attempt to load the image from where the JNI4NET libraries were located at, the only workaround (AFAIK) was to copy the whole libraries to your source directory, and compile your package using the copied libraries, then it will work.