Running JNI program - java-native-interface

I am running my first program in ubuntu.
But there was an error when I tried to run it:
public class HelloWorld {
public native String nativeHelloWorld();
static {
System.loadLibrary("HelloWorld");
}
public void print(){
{
String str = nativeHelloWorld();
System.out.println(str);
}
}
public static void main(String[] args) {
(new HelloWorld()).print();
return;
}
}
this error was found :
Exception in thread "main" java.lang.UnsatisfiedLinkError:HelloWorld.nativeHelloWorld()Ljava/lang/String;
how can I solve this error?

For Running JNI program in android, You should look at steps described here, You will need to build the native code using this command
cd <ndk-root>/samples/hello-jni
<ndk_root>/ndk-build
After successful build you will get the .so file in this directory,
\hello-jni\libs\armeabilib\hello-jni.so
Assuming you are trying to execute HelloJNi sample program from SDK. Once you got that file in libs directory, Run the project using eclipse simple run button and you will have your HelloWorld :).

These lines taken from Getting Stated JNI from SUN site
Make sure that the native library resides in one of the directories in
the native library path. If you are running on a Solaris system, the
LD_LIBRARY_PATH environment variable is used to define the native
library path. Make sure that it includes the name of the directory
that contains the libHelloWorld.so file. If the libHelloWorld.so file
is in the current directory, you can issue the following two commands
in the standard shell (sh) or KornShell (ksh) to set up the
LD_LIBRARY_PATH environment variable properly:
LD_LIBRARY_PATH=.
export LD_LIBRARY_PATH

Related

Error while loading shared object file: No such file or directory

I am trying to generate a usable binary for GCBM, a C++ carbon accounting tool. The binary has been generated from a GitHub Action workflow which is available as an artifact here: https://nightly.link/HarshCasper/moja.canada/actions/runs/1999997115/GCBM.zip
I downloaded the ZIP, unzipped it inside a gcbm directory, cd inside it, and tried launching the binary through:
./moja.cli
I got the following error:
./moja.cli: error while loading shared libraries: libmoja.flint.so.1: cannot open shared object file: No such file or directory
I have tried various ways to fix it by following other StackOverflow threads but nothing really has worked out. Can anyone please help me solve it?
From the error, it's clear library path that the executable looking for is not present. It happens sometimes if the executable compiled on another system takes a hardcoded library path that is not present on your system. The solution is you have to compile source on your system. Better compile it with a STATIC library. Make changes to Cmake(https://github.com/HarshCasper/moja.canada/blob/bffb196222e118e6797afa2bedab02dbe29dd330/Source/CMakeLists.txt#L47). or copy shared library to proper path.
Example, how to run GCBM/moja.cli with the ~40 internal shared libraries
mkdir GCBM && cd GCBM/
unzip GCBM.zip
chmod +x moja.cli
## create a script moja.sh to run moja.cli :
#!/bin/sh
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
exec ./moja.cli
## make the script executable and run ./moja.sh

VS code: Useless file keep appearing

Visual Studio Code 1.46.1
Operating system: MacOS 10.15.4 (Catalina)
VS Code Package used: C/C++, Code Runner
Problem: When I run a C++ code using Code Runner, a file with no extension automatically appear.
I would like to know what does this 'useless file' do, and how to make these files stop from spawning.
That is the executable file also called binary file. They are the executable like .exe in windows so it is very useful(as it is the output of source code). If you dont want to see that file in sidebar of vscode then there is a good answer to this question. Alternatively you can configure your build configuration file (located at .vscode in you working directory) and set the build path to somewhere else
You are using Code Runner extension on vscode then you can modify the execution command.
Go to Code-runner: Executor Map Setting
I did this:
"code-runner.executorMap": {
...
"c": "cd $dir && gcc $fileName -o ./temp/$fileNameWithoutExt && $dir./temp/$fileNameWithoutExt",
...
}
create a temp folder.
Now your temp folder will contain those unwanted files.
You can modify execution command like this for c++ also.

Use QProcess with a executable in resource [duplicate]

I'm writing a cross-platform C++ program using Qt and I want to package/embed a number of binary executables within the program. The program should be able to execute these binaries at runtime.
I figured, I would need QResource and QProcess using start() and the ":/..." notation, but I don't seem to get the process running. Is there anything I am missing? Should it work like this? Does the binary need to be set as executable?
Background: I am writing a tool which uses Git and I don't want to require the end-user to install Git manually.
(Trying this on Mac OS X, BTW.)
Update:
I am using the following code (C++, Qt on Mac OS X):
QString program = ":/git";
QStringList arguments;
arguments << "help" << "commit";
myProcess->start(program, arguments);
The Git executable is in the project path, my resources.qrc references it like so:
<qresource prefix="/">
<file>git</file>
</qresource>
I'm not getting an error, but the program is not executed. Behavior is the same when I set program to a non-existing file. Replacing ":/git" by the absolute path to git works perfectly.
You can't execute a program directly from a resource.
If you had a program in a resource and you wanted to execute it, you'd first have to read it out of the resource, write it to a file, make the file executable, then execute it.
Also, when you say that you're not getting an error, that probably means that you aren't checking for errors properly.
Several years late, but the question is still relevant. I had the same problem when wanting to embed rclone.
In the .pro file, add
# From http://stackoverflow.com/a/37561981
defineReplace(copyToDir) {
files = $$1
DIR = $$2
LINK =
for(FILE, files) {
LINK += $$QMAKE_COPY $$shell_path($$FILE) $$shell_path($$DIR) $$escape_expand(\\n\\t)
}
return($$LINK)
}
defineReplace(copyToBuilddir) {
return($$copyToDir($$1, $$OUT_PWD))
}
# Copy the binary files dependent on the system architecture
win32 {
message("Windows")
QMAKE_POST_LINK += $$copyToBuilddir($$PWD/rclone/windows/rclone.exe)
}else: unix:!macx {
message("Linux")
QMAKE_POST_LINK += $$copyToBuilddir($$PWD/rclone/linux/rclone)
}else: macx: {
# Here we want to place the binaries inside the application bundle, so the
# QMAKE_POST_LINK approach will not work because it places them in the same
# directory as the bundle and not inside it. Instead, use QMAKE_BUNDLE_DATA.
message("macOS")
MediaFiles.files += $$PWD/rclone/macOS/rclone
MediaFiles.path = Contents/MacOS
QMAKE_BUNDLE_DATA += MediaFiles
}
Notice how there are slight differences for each platform, but in general the approach is the same.
qmake will copy this files to the destination directory, and they will be accessible by simply making the process call to the local relative directory.
In the following code, I call the executable from QML, and it's going to be very similar in C++ as well:
var rcloneCommand
if (Qt.platform.os === "windows") {
console.log("Windows")
rcloneCommand = "rclone.exe"
} else {
console.log("OSX/Linux")
rcloneCommand = "./rclone"
}
qProcess.start(rcloneCommand, ["--config", "rclone.conf", "-v", "copy", "--stats", "1s", source, destination]);
I don't think resources would work. Processes are created by operating system, and resources are handled by application.
One possible solution would be bundle additional executables somewhere in your application directory and execute them from that path.
So the problem doesn't seem to be extracting the git executable from the resource so much as executing it?
The git program is generate don disk correctly, can you check it's permissions ?

Running JNI program in ubuntu

I am running my first program in ubuntu.
But there was an error when I tried to run it:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1681)
at java.lang.Runtime.loadLibrary0(Runtime.java:840)
at java.lang.System.loadLibrary(System.java:1047)
at JNIFoo.<clinit>(JNIFoo.java:6)
Could not find the main class: JNIFoo. Program will exit.
These lines taken from Getting Stated JNI from SUN site
Make sure that the native library resides in one of the directories in
the native library path. If you are running on a Solaris system, the
LD_LIBRARY_PATH environment variable is used to define the native
library path. Make sure that it includes the name of the directory
that contains the libHelloWorld.so file. If the libHelloWorld.so file
is in the current directory, you can issue the following two commands
in the standard shell (sh) or KornShell (ksh) to set up the
LD_LIBRARY_PATH environment variable properly:
LD_LIBRARY_PATH=.
export LD_LIBRARY_PATH
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
Fix your library path and try again.

Jni Example in Eclipse

Hi while trying out jni example in this link http://wendro.blogspot.com/2010/03/jni-example-eclipse-dev-cpp.html?showComment=1309930446765#c5048550711511727724
with eclipse Helios windows xp am getting this error in eclipse console
"error: cannot access MyFirstWrapper,
class file for MyFirstWrapper not found,
javadoc: error - Class MyFirstWrapper not found.
Error: No classes were specified on the command line. Try -help."
what i have to do..???
Alternatively, set your run configuration's Working Directory to the project's bin. in the arguments, set flag -d to change where the output file goes to your cpp folder. For example:
Working Directory: ${workspace_loc:/ProjectRoot/bin}
Arguments: -d ${workspace_loc:/ProjectRoot/cpp} full.package.name.path.to.Class
Hi Thanks i only got the answer
i did like this i got a jni header file generated inside cpp folder
In Eclipse Run Tools, External Tools Configurations,
Name:Jni
Location:My javah.exe location
D:\ProgramFiles\Java\jdk1.6.0_17\bin\javah.exe
Working Directory: my javah file location
${workspace_loc:/jni_hello_world/cpp}
And the most important point is inside Arguments we have to give first as our .class location then jni command like below
-classpath E:\Workspace\JNI\jni_hello_world\bin
-jni MyFirstWrapper