Solved

More problems with using jni?

Posted on 2000-04-20
16
303 Views
Last Modified: 2013-11-23
I tried the following but I get this error when I run the app:

I create a java package:

package jifwini;


public class JProfileIO
{
    static
      {
            // Used to load the library
        System.loadLibrary("jifwini");
    }
   
      public JProfileIO(){}
      public native boolean T();
}

then i compile it as following then
create a jar file

source for making the jar file:

cd c:\toolkit\jifwini\jar
del jifwini.jar


jar cf c:\toolkit\jifwini\jar\jifwini.jar -C c:\toolkit\jifwini\class jifwini\JProfileIO.class

then I create a javah file:

del c:\toolkit\jifwini\win32dll\JProfileIO.h

javah -jni -d "c:\toolkit\jifwini\win32dll" -classpath "c:\toolkit\jifwini\class\jifwini" JProfileIO

then i create a dll.  
I created a directory in my c:\temp\jio
where I place the dll.

My java app that uses the jni is as follows:

import jifwini.*;

class Test
{
      public static Test obT;
      String strValue;
      
      public Test()
      {
            Test1();
      }
        
      public void Test1()
      {
            strValue = "Test this one";
            System.out.println( strValue );            

            JProfileIO io = new JProfileIO();
            if( io.T() == true )
                  System.out.println( "true" );
            else
                  System.out.println( "false" );

      }
      
      public static void main(String[] args)
      {
            Test objT = new Test();
      }
      
}


Then i compile and run it:

javac -classpath "c:\temp\jio\jifwini.jar;c:\temp\jio" *.java
java -classpath "c:\temp\jio\jifwini.jar;c:\temp\jio" Test


now it compiles fine but when it runs I get the following erro:



Exception in thread "main" java.lang.UnsatisfiedLinkError: T
at jifwini.JPRofileIO.T(Native Method)
at Test.Test1(Test.java:19)
at Test.<init>(Test.java:10)
at Test.main(Test.java:31)

Here is what the dll does:

JNIEXPORT jboolean JNICALL Java_JProfileIO_T
  (JNIEnv *env, jobject this)
{
      return (JNI_TRUE);
}

0
Comment
Question by:eric07
  • 6
  • 5
  • 5
16 Comments
 
LVL 19

Accepted Solution

by:
Jim Cakalic earned 20 total points
ID: 2737014
Several suggestions, in no particular order:

1) In the System.loadLibrary() call, specify the extension of the file. This removes any ambiguity as to whether the ".dll" extension will be automatically appended to the library name.
    System.loadLibrary("jifwini.dll");

2) Make sure the directory where you installed the dll is defined in your PATH environment variable. This is where Windows will look for the dll when asked to load it. Since you created a directory in the temp tree, I doubt that it is in your PATH.
    set PATH=%PATH%;C:\temp\jio

3) When running javah, supply the fully qualified class name as the final argument as specified in the documentation for the javah tool. Naturally, this will also change the name of the generated header file.
    javah ... jifwini.JProfileIO

4) The name of the C++ method should be of the form: "Java_" + package + "_" + class + "_" + method. This will be the method prototype in the generated header file if you follow step 3 above.
    JNIEXPORT jboolean JNICALL Java_jifwini_JProfileIO_T(JNIEnv *env, jobject this)

Best regards,
Jim Cakalic
0
 
LVL 3

Expert Comment

by:falter
ID: 2737490
eric07,

In extension what Jim is saying at 1) and 2)
you can use
                    System.load("c:\\temp\\jio\\jfiwini.dll");

I never tried this because the parm of load is a platform and installation specific filename.
only run at one platform.

regards
jf                
               
0
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 2737611
Actually, no, I wouldn't suggest embedding the full path of the dll in the argument to loadLibrary. This may be useful as a troubleshooting measure but not appropriate for deployment as it requires installation in a specific location for the application to work.

What I suggested was that the extension ".dll" might be required to properly locate and load the library. I don't know whether, somewhere along the way from your loadLibrary() to the low-level kernel call that performs, something will try to find the file and append various extensions if the file name as supplied cannot be located. This would not be unusual behavior for this kind of call. (Consider ".exe" v. ".com" v. ".bat".) I just don't know if it will happen in this case.

Anyway, this is only one of several proposals for what could be wrong. It may be part of the problem but I doubt that it is the complete problem.

Jim Cakalic
0
 
LVL 3

Expert Comment

by:falter
ID: 2738020
Jim,
I agree with you that System.load is only for troubleshooting.

As I know System.loadLibrary("jfiwini") will extend the paramter to an OS specific shared library name.

Means in
Windows environment:
something like jfiwini.dll
AIX and most Unix envs: libjfiwini.{a,so,sl} with different ordering how the suffixes are tried.

So I think doing something like loadLibrary("jfiwini.dll") may result in looking for
jfiwini.dll.dll ??

regards
jf
0
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 2738181
I've only written two JNI interfaces, both on Windows NT 4. I've never actually tried calling loadLibrary without specifying the extension on the name of the library. This is why I'm sure that in a Windows environment, "jfiwini.dll" will work and uncertain as to whether "jfiwini" without the extension might work.

Thanks for the clarification, though. I'll have to read the jdk docs on System.loadLibrary and System.load to improve my understanding of their behavior.

Best regards,
Jim
0
 

Author Comment

by:eric07
ID: 2738213
I keep getting the same error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no jifwini.dll in java.library.path
at java.lang.ClassLoader.loadlibrary( unknonw source )
at java.lang.Runtime.loadlibrary0(Unknown Source )
at java.lang.System.loadlibrary(Unknown Source )
at jifwini.JProfileIO.<clinit>(JProfileIO.java:14)
at Test.<init>(Test.java:10)
at Test.main(Test.java:31)

I did the echo %path% to get the paths where I would be able to place my dll.

C:\database\orant\bin;C:\WINNT\system32;
C:\WINNT;C:\WINNT\System32\Wbem;
c:\database\MSSQL7\BINN;C:\Program Files\Symantec\pcAnywhere\;;
c:\java\jdk1.3\bin;

I put it in my c:\winnt\system32
any ideas on this
0
 

Author Comment

by:eric07
ID: 2738215
I keep getting the same error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no jifwini.dll in java.library.path
at java.lang.ClassLoader.loadlibrary( unknonw source )
at java.lang.Runtime.loadlibrary0(Unknown Source )
at java.lang.System.loadlibrary(Unknown Source )
at jifwini.JProfileIO.<clinit>(JProfileIO.java:14)
at Test.<init>(Test.java:10)
at Test.main(Test.java:31)

I did the echo %path% to get the paths where I would be able to place my dll.

C:\database\orant\bin;C:\WINNT\system32;
C:\WINNT;C:\WINNT\System32\Wbem;
c:\database\MSSQL7\BINN;C:\Program Files\Symantec\pcAnywhere\;;
c:\java\jdk1.3\bin;

I put it in my c:\winnt\system32
any ideas on this
0
 

Author Comment

by:eric07
ID: 2738376
OK I solved to problem.  Now it seems thought that when I put it into a jar file I cant get it to run.  When I put it outside of a jar file it works great.

This is the error I get:
Exception in thread "main" java.lang.UnsatisfiedLinkError: T
at jifwini.JProfileIO.T(Native method)
at Test.Test1.(Test.java:19);
at Test.<init>(Test.java:10)
at Test.main(Test.java:31)

it seems like it cant find the class in the jar file.

This is the way I compile my jar file:

del /q c:\toolkit\jifwini\class\jifwini\*.*
del /q c:\toolkit\jifwini\jar\*.*
c:
cd\
cd c:\toolkit\jifwini\source
javac -d "c:\toolkit\jifwini\class" JProfileIO.java


cd..

then I build the jar file
cd c:\toolkit\jifwini\jar
del jifwini.jar

jar cf c:\toolkit\jifwini\jar\jifwini.jar -C c:\toolkit\jifwini\class jifwini\JProfileIO.class

and when I run it with the sample :

javac -classpath "c:\temp\jio\jifwini.jar;c:\temp\jio" *.java

java -classpath "c:\temp\jio\jifwini.jar;c:\temp\jio" Test

Any ideas on this.

Again if I dont put it in a jar file it works great.

Thanks
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 3

Expert Comment

by:falter
ID: 2739263
Hey eric07,

UnsatisfiedLink always says your OS cannot load the library.
The shared library should be somewhere in your path!
One location to try is your java/bin directory.

I have mentioned ./winnt/system32 is not a good location without rebooting. I didn't find any documentation about this, but  it seems like NT is only loading existing DLL's at boot time from this directory.

And another thing may be your DLL is using a second one f.e. C-Runtime library of your Compiler and this one  cannot be loaded this will result in the same error.

Of course you should not put the DLL in your JAR file.
I never tried this.

regards
jf
0
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 2741821
Yes, definitely do not put the DLL in a jar file. The DLL is an operating system specific executable code file. The OS doesn't understand jar files. It will not be able to look inside, extract the DLL, and load it. This means that you will have to install two files on target machines. I don't know any way around this.

Jim
0
 

Author Comment

by:eric07
ID: 2744663
You know what the problem was. it was the way I did the javah.

I just did the javah -jni filename
instead of the the package.filename

javah ... jifwini.JProfileIO

after doint this it solved my problem.

Thanks
0
 
LVL 3

Expert Comment

by:falter
ID: 2746736
If I try javah -jni whitout package name javah gives me an error, so there must be a class JProfileIO without a package or you missed the error.

regards
jf
0
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 2747983
What version of the jdk are you using? I've tried javah on 1.2.1 and 1.3rc2 with the same results. I was able to run javah using the following incantation:

    javah JProfileIO

On each occasion it produced a JProfileIO.h file with containing a prototype for the method Java_JProfileIO_T. At the time of running this command, the current directory contained a JProfileIO.class file. Perhaps this is why you got an error?

When you run it using the fully qualified classname you must remember to have the class properly located in a directory that can be reached by appending the package names to a directory found in the CLASSPATH variable. In other words, to run

    javah jifwini.JProfileIO

you must have JProfileIO.class in a directory name jifwini that is a subdirectory of one of the entries in CLASSPATH. Otherwise javah will tell you that it cannot find the class.

BTW, specifying '-jni' is optional as this is the default for javah.

Jim Cakalic
0
 
LVL 3

Expert Comment

by:falter
ID: 2748244
Jim,
I'm using JDK 1.1.8 on AIX and javah gives me an error no such class if try to run it without the fully qualified classname.

Same under Linux with JDK 1.1.8

jf
0
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 2751204
Eric, is your problem solved? Do you think you are ready to select the answer to your question?
0
 

Author Comment

by:eric07
ID: 2752063
You know what Jim.  I selected your answer several days back.  This is weird but I was able to solve it by using javah the way you explained it.  With the package.filename

Works great

Thanks all
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
scoresSpecial  challenge 13 42
countHi2 challenge 7 44
Requested array size exceeds VM limit 3 51
maven project error 5 24
By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now