Loading native library in Quarkus application - java-native-interface

I need to load a native library (.so file) and its java wrapper jar in a quarkus web application.
If I use System.loadLibrary call as a static initializer in my Resource, I get" Native Library /usr/local/lib/heavy_calc.so already loaded in another classloader" when the first GET request is hit.
I am running the application in IntelliJ using
./mvnw compile quarkus:dev
What is the best way to handle loading native libraries? Below is the snippet of code loading the library:
#Path("/hello")
public class ExampleResource {
static {
//export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
System.loadLibrary("HeavyCalcJNI");
}
#GET
#Produces(MediaType.TEXT_PLAIN)
public String hello() {
Calc calc = new Calc();//class from jni wrapper jar
return calc.compute();
}
}
Any help is much appreciated.
Thanks

Related

How to run a c++ function using MSBuild targets?

I am using MSBuild and I came across this topic called Targets that lets you perform some tasks before building the project.
I need to run a C++ function which is present in a .cpp file in my (.sln) solution file. I came across this example to run a task, but it is written in C#.
using System;
using Microsoft.Build.Utilities;
namespace SimpleTask1
{
public class SimpleTask1: Task
{
public override bool Execute()
{
// This is where the task would presumably do its work.
return true;
}
}
}
So basically, I want run a C++ function before the building my solution file and I am confused on how to use MSBuild tasks and targets for this purpose. This C++ function actually generates some code that is necessary for successful building, else the build would fail.

UWP App Crash at Class1 c1 = new Class1(); saying - The specified module could not be found. (Exception from HRESULT: 0x8007007E

I am trying to create a library of fftool so that the uwp app doesn't have to launch a process to run FFmpeg exe out of the environment and yet able to run all command of fftool. so, for that
first, I created a static lib compiling fftool c code adding all the necessary linking and include
then I created a WinRT component in c++ to connect this library to my uwp app
so, again provided all the input, link, include and then added a reference to the static library to it.
since both of them are in the same solution.
so, I did not add a reference to the linker and include for the static library in the WinRT component
then for the test, I created a class calling a simple function that I added to c manually
but now whenever I try to create an object of that test class it throws an error saying
-The specified module could not be found. (Exception from HRESULT: 0x8007007E)
and this is all at runtime
while compiling and launching of the app in c# work fine.
but if I use the c++ app it crashes as it launches
and also I am new to c and c++ I didn't use the c/c++ before that so I am stuck at it and unable to understand what's wrong and I tried googling it but I am unable to find something
thanks
ok so it looks like my app is unable to find FFmpeg core dll as avcodec, avfilter, etc so now I added them to exe location and it worked ok

How do I add MinGW Kotlin Native dependencies

I'm trying to create a small application that will be able to communicate with the AWS IoT service. Since I want it to be fairly small and I wanted to try something new, I decided to go for Kotlin Native. I quickly noticed that AWS has released their C++ library that allows you to easily connect to the AWS IoT service (https://github.com/aws/aws-iot-device-sdk-cpp/tree/release) I downloaded it and even managed to compile with MinGW (yes, I'm on Windows). I noticed that it generated a bunch of *.o files. I reckon this is now the right time to import it to my Kotlin Native project. My build.gradle file for now looks completely standard
plugins {
id 'kotlin-multiplatform' version '1.3.11'
}
repositories {
mavenCentral()
}
kotlin {
targets {
// For ARM, preset should be changed to presets.iosArm32 or presets.iosArm64
// For Linux, preset should be changed to e.g. presets.linuxX64
// For MacOS, preset should be changed to e.g. presets.macosX64
fromPreset(presets.mingwX64, 'mingw')
configure([mingw]) {
// Comment to generate Kotlin/Native library (KLIB) instead of executable file:
compilations.main.outputKinds('EXECUTABLE')
// Change to specify fully qualified name of your application's entry point:
compilations.main.entryPoint = 'sample.main'
}
}
sourceSets {
// Note: To enable common source sets please comment out 'kotlin.import.noCommonSourceSets' property
// in gradle.properties file and re-import your project in IDE.
mingwMain {
}
mingwTest {
}
}
}
task runProgram {
def buildType = 'release' // Change to 'debug' to run application with debug symbols.
dependsOn "link${buildType.capitalize()}ExecutableMingw"
doLast {
def programFile = kotlin.targets.mingw.compilations.main.getBinary('EXECUTABLE', buildType)
exec {
executable programFile
args ''
}
}
}
for some reason I cannot find any examples as to how to add my freshly complied dependency. Normally when you code C++ you have to specify the path to Include directory and the Lib directory separately. AFAIK this is not something that gradle provides out of the box. How can I import this dependency then? Or perhaps there's some centralised repository I could simply pull such dependency from, like in pretty much every other programming language that is still used nowadays? At least this specific library doesn't seem to be available on NuGet :/
Kotlin/Native is not[1] interoperable with C++ at this moment. You can however create C wrapper for any C++ library and it's functions from Kotlin/Native[2].
When using multiplatform gradle plugin you can define native interop with this syntax:
kotlin {
linuxX64 { // Replace with a target you need.
compilations.main {
cinterops {
myInterop {
// Def-file describing the native API.
// The default path is src/nativeInterop/cinterop/<interop-name>.def
defFile project.file("def-file.def")
// Package to place the Kotlin API generated.
packageName 'org.sample'
// Options to be passed to compiler by cinterop tool.
compilerOpts '-Ipath/to/headers'
// Directories for header search (an analogue of the -I<path> compiler option).
includeDirs.allHeaders("path1", "path2")
// Additional directories to search headers listed in the 'headerFilter' def-file option.
// -headerFilterAdditionalSearchPrefix command line option analogue.
includeDirs.headerFilterOnly("path1", "path2")
// A shortcut for includeDirs.allHeaders.
includeDirs("include/directory", "another/directory")
}
anotherInterop { /* ... */ }
}
}
}
}
If you only define the interop name the plugin will look for .def file[3] in src/nativeInterop/cinterop/ directory and use it (in this case src/nativeInterop/cinterop/myInterop.def).
kotlin {
linuxX64 {
compilations.main {
cinterops {
myInterop {
}
}
}
}
}
The .def files[3] contains information about the library you are trying to use and typically look like this.
headers = png.h
headerFilter = png.h
package = png
More information about cinterop: https://kotlinlang.org/docs/reference/native/c_interop.html
More information about multiplatform projects: https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html

Python extension building with boost

I am fairly new to the boost c/c++ library. I downloaded boost library and build the library.
I created a very simple python library in c++ using boost interface (actually it is example code given in the documentation). I built it into a dll file. In the documentation it reads that this dll is exposed to python and they just show the import function in python and include the created library.
I don't understand how to expose that dll to python and load the library inside in tradition ('import') manner.
In case if you wanna look at the code then here it is:
#include <boost/python.hpp>
char const* greet()
{
return "hello, world";
}
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
Please help I really want to build applications with c/c++ and python.
I simply want to use hello_ext as:
>>>import hello_ext
>>>print hello_ext.greet()
Thank you.
I built it into a dll file. In the documentation it reads that this dll is exposed to python and they just show the import function in python and include the created library. I don't understand how to expose that dll to python and load the library inside in tradition ('import') manner.
You need to put that shared library into the module search path. There are a few ways to achieve that.
One is:
import sys
sys.path.append("<directory-where-hello_ext-module-resides>")
import hello_ext
Your shared library should be called hello_ext.dll.

Running JNI program

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