Solved

More problems with using jni?

Posted on 2000-04-20
16
337 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
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
 
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

Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
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…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Suggested Courses

628 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