I've try the Hello world JNI from:
http://home.pacifier.com/~mmead/jni/cs510ajp/
I did the Java class:
public class ACTICamWrapperJNI {
public native void displayMessage();
static
{
System.loadLibrary("HelloWorldImp");
}
}
and call it in:
public static void main(String args[]) {
//</editor-fold>
System.out.println(System.getProperty("java.library.path"));
ACTICamWrapperJNI test = new ACTICamWrapperJNI();
}
the cpp file looks like:
#include <stdio.h>
#include "HelloWorld.h" // this header file was generated by javah
JNIEXPORT void JNICALL Java_HelloWorld_displayMessage(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
}
I have switch to JDK x86 and compiled with X86:
C:\Development\testJNI>javac HelloWorld.java
C:\Development\testJNI>javac HelloWorld.java
C:\Development\testJNI>javah -jni HelloWorld
I used the gcc of MINGW32 I had in QT folder (hope that is ok)
C:\Development\testJNI>gcc -shared -I "C:\Program Files (x86)\Java\jdk1.7.0_40\include" -I"C:\Program Files (x86)\Java\jdk1.7.0_40\include\win32" HelloWorld.cpp -o HelloWorldImp.dll
Note I had to add shared otherwise I got the error:
undefined reference to `WinMain#16'
C:\Development\testJNI>"C:\Program Files (x86)\Java\jdk1.7.0_40\bin\java.exe" Main
Exception in thread "main" java.lang.UnsatisfiedLinkError: HelloWorld.displayMessage()V
at HelloWorld.displayMessage(Native Method)
at Main.main(Main.java:9)
Note that I've make sure that I'm running the java of x32 jdk and compiled with the x32 version too as I have the x64 on my system too.
Tried on NetBean IDE as well and got the issue:
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Windows\System32\HelloWorldImp.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1957)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1882)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1872)
at java.lang.Runtime.loadLibrary0(Runtime.java:849)
at java.lang.System.loadLibrary(System.java:1087)
at au.com.ricor.ACTICamWrapperJNI.<clinit>(ACTICamWrapperJNI.java:15)
at au.com.ricor.CameraPanel.main(CameraPanel.java:58)
As well the version of gcc I use is:
C:\Development\testJNI>gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/qt/tools/mingw48_32/bin/../libexec/gcc/i686-w64-mingw32/4
.8.0/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: ../../../src/gcc-4.8.0/configure --host=i686-w64-mingw32 --buil
d=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32 --with-sysroot=/t
emp/x32-480-posix-dwarf-r2/mingw32 --enable-shared --enable-static --disable-mul
tilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-
threads=posix --enable-libgomp --enable-lto --enable-graphite --enable-checking=
release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --d
isable-sjlj-exceptions --with-dwarf2 --disable-isl-version-check --disable-cloog
-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --disable-boots
trap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --d
isable-symvers --with-gnu-as --with-gnu-ld --with-arch=i686 --with-tune=generic
--with-host-libstdcxx='-static -lstdc++' --with-libiconv --with-system-zlib --wi
th-gmp=/temp/mingw-prereq/i686-w64-mingw32-static --with-mpfr=/temp/mingw-prereq
/i686-w64-mingw32-static --with-mpc=/temp/mingw-prereq/i686-w64-mingw32-static -
-with-isl=/temp/mingw-prereq/i686-w64-mingw32-static --with-cloog=/temp/mingw-pr
ereq/i686-w64-mingw32-static --enable-cloog-backend=isl --with-pkgversion='rev2,
Built by MinGW-builds project' --with-bugurl=http://sourceforge.net/projects/mi
ngwbuilds/ CFLAGS='-O2 -pipe -I/temp/x32-480-posix-dwarf-r2/libs/include -I/temp
/mingw-prereq/x32-zlib/include -I/temp/mingw-prereq/i686-w64-mingw32-static/incl
ude' CXXFLAGS='-O2 -pipe -I/temp/x32-480-posix-dwarf-r2/libs/include -I/temp/min
gw-prereq/x32-zlib/include -I/temp/mingw-prereq/i686-w64-mingw32-static/include'
CPPFLAGS= LDFLAGS='-pipe -L/temp/x32-480-posix-dwarf-r2/libs/lib -L/temp/mingw-
prereq/x32-zlib/lib -L/temp/mingw-prereq/i686-w64-mingw32-static/lib -L/temp/x32
-480-posix-dwarf-r2/mingw32/opt/lib'
Thread model: posix
gcc version 4.8.0 (rev2, Built by MinGW-builds project)
Thanks
William
Either rename the class from au.com.ricor.ACTICamWrapperJNI to HelloWorld, or the native function (in C++ file) from Java_HelloWorld_displayMessage() to Java_au_com_ricor_ACTICamWrapperJNI_displayMessage()
I know this has an answer, but I determined that if you are compiling as Debug, it is not redistributable to another PC; you can try compiling for Release, and that should work. I just used this to resolve my own issue.
Related
I'm trying to work build my very first JNI application, following this tutorial: https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
Problem Summary: While running my application, I get an java.lang.UnsatisfiedLinkError error.
First I wrote the Class HelloJNI.java:
public class HelloJNI {
static {
System.loadLibrary("hello"); // Load native library at runtime
// hello.dll (Windows) or libhello.so (Unixes)
}
// Declare a native method sayHello() that receives nothing and returns void
private native void sayHello();
// Test Driver
public static void main(String[] args) {
new HelloJNI().sayHello(); // invoke the native method
}
}
This class I compiled with:
javac HelloJNI.java
Next I ran javah HelloJNI
This produced the following file HelloJNI.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */
#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloJNI
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJNI_sayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Next I implemented HelloJNI.c:
#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"
// Implementation of native method sayHello() of HelloJNI class
JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {
printf("Hello World!\n");
return;
}
Finally I compiled the c class:
gcc -I"/usr/lib/jvm/java-8-oracle/include" -I"/usr/lib/jvm/java-8-oracle/include/linux" -c -Wall -Werror -fpic HelloJNI.c
gcc -shared -o hello.so HelloJNI.o
This produces the files hello.so and HelloJNI.o. Next I try to run the code:
java -Djava.library.path=. HelloJNI
This produces the error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at HelloJNI.(HelloJNI.java:3)
This seems to be the most common JNI error on the internet... My method names seem to be correct. I also ran:
nm hello.so | grep say
This gives me: 00000000000006b0 T Java_HelloJNI_sayHello which seems to be correct, i.e. the compiler didn't add additional characters. I simply ran out of ideas of things I could try. Any suggestions?
My OS: Linux Mint 13, GCC version 4.7.3, java version 1.8.0_60
==========UPDATE===============
When I replace System.loadLibrary("hello"); by System.load("/usr0/home/jkinable/workspace/javaIDEA/jnitest/hello.so"); my HelloWorld example works! However, I don't want to use an absolute path so I'm still looking for a way to use System.loadLibrary("hello"); instead? Any suggestions? I've also tried running on a different linux system, but I get the same issue.
It turns out that the problem is due to some naming convention on unix/linux platforms! When using:
System.loadLibrary("hello");
the file should not be named hello.so! Instead, the name should be libhello.so. On Windows, use hello.dll. I'm surprised that this issue is not mentioned in IBM's JNI tutorial: http://www.ibm.com/developerworks/java/tutorials/j-jni/j-jni.html
I'm not sure what the rationality behind this issue is. Why would you load a library "hello" which should be named libhello.so on your filesystem (instead of hello.so)?
Hi guys i have tried all the solutions like
java -Djava.library.path=. demo
adding the dll path to PATH
java -Djava.library.path=c:\JNI\demo.dll demo
But still the above error.
Here is my java code..
class demo
{
public native void printline();
public static void main(String[]args)
{
new demo().printline();
}
}
Here is my c code...
#include<stdio.h>
#include<jni.h>
#include "demo.h"
JNIEXPORT void JNICALL Java_demo_printline(JNIEnv *a, jobject b)
{
printf("Hello wrold!!!");
return;
}
Steps for compiling and running,
javac demo.java
javah demo
gcc -c -I"c:\jdk1.7.0_55\include" -I"c:\jdk1.7.0_55\include\win32" demo.c
gcc -Wl,--add-stdcall-alias -shared -o demo.dll demo.c
java -Djava.library.path=c:\JNI\demo.dll demo
Am i going wrong somewhere?
can someone please help me out,.
Try Run-Time Loading of the dll file within the java code in a static block like:
static
{
System.loadLibrary("demo");
}
should give you the output.
Moreover make sure that dll file generated is x32 or x64 according to the gcc compiler in use.
looking for "JNI hello world" (or many other terms, possibly), would have given you the answer.
for example:
http://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
you need to load the library inside your java code
you need to specify the path to the directory of the library, not to the library itsself, in java.library.path
I'm trying to call a C function inside a Java code.
I have this hava code.
public class JavaToC {
public native void helloC();
static {
System.loadLibrary("HelloWorld");
}
public static void main(String[] args) {
new JavaToC().helloC();
}
}
. I compiled it and then created header file. Then make the following HelloWorld.c file.
#include <stdio.h>
#include <jni.h>
#include "JavaToC.h"
JNIEXPORT void JNICALL Java_JavaToC_helloC(JNIEnv *env, jobject javaobj)
{
printf("Hello World: From C");
return;
}
I tried compiling this using "gcc -o libHelloWorld.so -shared -I/usr/java/include -I/usr/java/include/solaris HelloWorld.c -lc", but it gives the following result.
Text relocation remains referenced
against symbol offset in file
.rodata (section) 0x9 /var/tmp//cc.GaGrd.o
printf 0xe /var/tmp//cc.GaGrd.o
ld: fatal: relocations remain against allocatable but non-writable sections
collect2: ld returned 1 exit status
I'm working on Solaris 11, how can I solve this?
I cannot test this on a Solaris machine at the moment, but from http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/SPARC-Options.html
-mimpure-text suppresses the “relocations remain against allocatable but non-writable sections” linker error message. However, the
necessary relocations will trigger copy-on-write, and the shared
object is not actually shared across processes. Instead of using
-mimpure-text, you should compile all source code with -fpic or -fPIC.
the solution seems to be to add the -fpic option to generate position-independent code.
I'm quite a newbie to Java JNI. I tried a helloCPP program but ran into problems. here's my code :
helloCPP.java;
public class helloCPP {
public native void hellocpp ();
static {
System.loadLibrary("helloCPP");
}
public static void main (String [] args) {
helloCPP hcpp=new helloCPP ();
hcpp.hellocpp ();
System.exit (0);
}
}
Then here's my hellocpp.cpp out of which I made helloCPP.dll ;
#include <iostream>
#include "helloCPP.h"
using namespace std ;
JNIEXPORT void JNICALL Java_helloCPP_hellocpp. (JNIEnv *env, jobject obj) {
cout <<"hello java, I'm c++\n";
}
int main (){};
I successfully built the helloCPP.dll. But when I try to run java helloCPP, I get this error:
Exception in thread "main"
java.lang.UnsatisfiedLinkError: helloCPP.hellocpp () V
at helloCPP.hellocpp(Native Method)
at helloCPP.main (helloCPP.java :8)
I'm doing all these stuff on a Windows 8 x86 operating system.
These are the commands I wrote:
javac helloCPP.java
javah helloCPP
g++ -c hellocpp.cpp
g++ -o helloCPP.dll hellocpp.cpp
This one generated the error:
java HelloCPP
Thanks in advance.
Most likely, the Java run-time cannot locate the DLL file. You have run the Java application with additional arguments (assuming the DLL file is in the current directory):
java -Djava.library.path=. HelloCPP
Update:
EJP has a good point. I think your link command isn't correct. The second g++ command should be something like:
g++ -o helloCPP.dll -shared hellocpp.o
There are two changes: hellocpp.o instead of hellocpp.cpp and more importantly the option -shared to indicate that you want to create a shared library and not an executable.
The exact options depend on your platform. As you haven't specified it, I can't tell you for sure.
I want to call a C subroutine from Java. I'm using JNI. I have created the .java, .c, and .h files, and compiled a DLL. All the files are in the same folder. But when I run the program, it shows an unsatisfiedlinkError. Where am I going wrong...?
As I am learning JNI, the source code I used is the one from: http://www.ibm.com/developerworks/java/tutorials/j-jni/section2.html and things I have already tried:
Create a dll using Code::Blocks(ide) and GCC as the compiler
Create dll using GCC from command line (Ref. http://sig9.com/node/35 )
I am using Win7 32 bit, and I guess all the methods above generate 32-bit DLLs
All the solutions I found for creating a DLL (shared library) are for MS VC/VCPP and I don't have that on my machine right now.
Where is the problem? DLL files are being generated without any exception, but when I run the Java code, it throws the exception.
PS: If there is any theoretical examples that explains how JNI works and what actually it does, then kindly share the link...
The message or exception being thrown:
c:\myjava1>java Sample1
Exception in thread "main" java.lang.UnsatisfiedLinkError: Sample1.intMethod(I)I
at Sample1.intMethod(Native Method)
at Sample1.main(Sample1.java:11)
At the end of the day after creating dll file lots of times,I am pretty sure that there is possibly no issue with it ,something is wrong with the path ...I have changed the loadlibrary method with load method ,but still no luck,.....
as suggested by a MOD:
I have been discussing about this question on the post:JNI error while calling a C subroutine ,I am posting all the codes here as the comments have limited characters... Sample1.c
#include "jni.h"
#include"Sample_Sample1.h"
JNIEXPORT jint JNICALL Java_Sample_Sample1_test(JNIEnv *env, jobject obj){
return(1);
}
void main(){}
Sample1.java
package Sample;
public class Sample1
{
public native int test();
static{
System.loadLibrary("Sample1");
}
public static void main(String[] args)
{
Sample1 sample = new Sample1();
System.out.println(sample.test());
}
}
Sample_Sample1.h(generated using javah -jni command)
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class Sample_Sample1 */
#ifndef _Included_Sample_Sample1
#define _Included_Sample_Sample1
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Sample_Sample1
* Method: test
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_Sample_Sample1_test
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Can anyone guide me where the issue is?In earlier post I mentioned that the code I am using is the one from tutorials ,but to simplyfy the things I have changed the codes ...While using **java Sample.Sample1" i am getting:
c:\myjava1>java Sample.Sample1
Exception in thread "main" java.lang.UnsatisfiedLinkError: Sample.Sample1.test()I
at Sample.Sample1.test(Native Method)
at Sample.Sample1.main(Sample1.java:12)
You need to have your library explicitly set on your path.
It may be the case that the flags you are using there aren't quite right. Try this:
gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at \
-I[Java_HOME]/include -I[Java_HOME]/include/win32 \
-shared -o Sample1.dll Sample1.c
From MinGW GCC site.
Have you checked your DLL by calling it from a stub C++ application? Pay particular attention to the exact name (including capitalisation) of the method(s) you are calling.
The Javadoc for UnsatisfiedLinkError says "Thrown if the Java Virtual Machine cannot find an appropriate native-language definition of a method declared native." That probably means either that the name is misspelled or your DLL is not where the JVM is expecting to find it.
Finally solved the problem using System.load() method, System.loadLibrary() Still doesn't work for me...it keeps on giving the same exception, And the I think the issue was with the .dll Thanks to all of you who supported and responded...
After spending 2hrs and analysing the code. Problem is with .dll/.so compilation. Below command works for me:
g++ -dynamiclib HelloJni.cpp -I /usr/include/ -I /usr/lib/jvm/java-1.8.0-openjdk-amd64/include/ -I /usr/lib/jvm/java-1.8.0-openjdk-amd64/include/linux/ -shared -o libHelloJni.so
or
g++ -dynamiclib HelloJni.cpp -I /usr/include/ -I $JAVA_HOME/include/ -I $JAVA_HOME/include/linux/ -shared -o libHelloJni.so
Above command is for linux. In case of Windows, change
[Java_HOME]/include/linux/ ---> [Java_HOME]/include/win/
Mac:
$Java_HOME/include/linux/ ---> $Java_HOME/include/darwin/