When I try to use my library.dll with java I have this error :
java.lang.UnsatisfiedLinkError: C:\Users\ledev\Desktop\library.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform
at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2424)
at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2481)
at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2678)
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2643)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:876)
at java.base/java.lang.System.loadLibrary(System.java:1875)
at JNI.HelloJNI.<clinit>(HelloJNI.java:6)
Exception in thread "main"
Here is my code main.c :
#include "main.h"
#include <stdio.h>
#include<stdlib.h>
DLL_EXPORT void hello_jni()
{
printf("Hello, JNI !");
}
Here is my main.h :
#ifndef __MAIN_H__
#define __MAIN_H__
#define BUILDING_DLL
#include <windows.h>
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
#ifdef __c
extern "C"
{
#endif
DLL_EXPORT void hello_jni();
#ifdef __c
}
#endif
#endif // __MAIN_H__
And here is my java code :
package JNI;
public class HelloJNI {
static {
System.loadLibrary("library");
}
private native void hello_jni();
public static void main(String[] args) {
new HelloJNI().hello_jni(); // invoke the native method
}
}
This is how I created my dll :
g++ -c -BUILD_DLL main.c
g++ -shared -o library.dll main.o -Wl,--out-implib,libexample_dll.a
I'm working under intellij IDEA for java and none particular IDE for my c code. My os is windows 10.
I don't really know what I have to modifiy to make it works. None of the topics I read helped me (for exemple : Create a valid shared library in C). If you need anything else, just tell me.
Related
I'm at a total loss here. I'm trying to get a JVMTI agent library running but it keeps crashing for some reason.
I've narrowed it down this line:
(*jvm)->GetEnv(jvm, (void**)jvmti, JVMTI_VERSION_1_0);
this is the full code of the agent lib (in C):
#include <jvmti.h>
#include <stdlib.h>
jvmtiEnv* jvmti = NULL;
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved)
{
printf("Agent started.\n");
_flushall();
jint err = (*jvm)->GetEnv(jvm, (void**)jvmti, JVMTI_VERSION_1_0);
if (err != JNI_OK)
{
printf("Failed to get JVMTI env!\n");
_flushall();
return err;
}
return JNI_OK;
}
JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM* vm, char* options, void* reserved)
{
return JNI_OK;
}
JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm)
{
}
As I tried to isolate what the issue was I wrote a very simple java app to test
this with:
public class Test
{
public static void main(String[] args)
{
System.out.println("Hello from java!");
}
}
If I run this from netbeans with the VM arg -agentpath set to my .dllcontaining the code above, the app seems to crash when it tries to call GetEnv().
I've made sure of the following things:
- The JVM and the dll are both 64bit.
- The library is most definitely being found and loaded (the printf output is visible before the crash.)
I don't know what else could probably be causing this, do I have to link against some JVMTI API lib that I don't know about?
Or could this be an issue with the java installation on my PC?
Thanks
You should be passing address of jvmti to GetEnv() as in:
jint err = (*jvm)->GetEnv(jvm, (void**) &jvmti, JVMTI_VERSION_1_0);
I have a simple class in Java:
public class MyClass
{
public static void dummyTest()
{
}
}
And in C++ I do the following JNI Call:
void c_call_function()
{
JNIEnv *env ...// the JNIEnv initialization in JNI...
jclass clazz ...// the class initialization in JNI...
jmethodID mid_dummyTest = env->GetStaticMethodID(clazz, "dummyTest", "()V");
env->CallStaticIntMethod(clazz, mid_dummyTest);
}
If a single program calls the static method c_call_function() it is ok.
But if a multithread program calls the c_call_function(), it gives me the following message, when passes the line env->CallStaticIntMethod(clazz, mid_dummyTest);:
Access violation at 0x000000006FC77154 read to 0x0000000000000000
If the program is multithread, it uses the same JNIEnv variable.
But I also tried to load the same JNIEnv via AttachCurrentThread method and it gives me the same problem.
What is the restriction when calling the method bellow by multiple threads as long as I don't create any local references or even delete or modify anything?
env->CallStaticIntMethod(clazz, mid_dummyTest);
env should be obtained separately for each thread. You should use AttachCurrentThread() if and only if a thread was *not started by JVM. For each thread that issues AttachCurrentThread(), you must call DetachCurrentThread().
clazz should be obtained separately for each thread, or you can save a global reference to the result received from FindClass().
mid_dummyTest can be saved in a global variable: this id is independent from the thread, env and clazz.
I a able to run similar code (look below) where I have multiple threads accessing the same JVM (macOS). I am using pthread.
Few things that are important
attaching thread to JVM ("The JNI interface pointer (JNIEnv) is valid only in the current thread. Should another thread need to access the Java VM, it must first call AttachCurrentThread() to attach itself to the VM and obtain a JNI interface pointer.")
joining threads
i guess it's a good idea to use mutex as well to prevent multiple threads being attached
main.c
#include <stdio.h>
#include <jni.h>
#include <pthread.h>
#define NUM_THREADS 6
pthread_mutex_t mutexjvm;
pthread_t threads[NUM_THREADS];
struct JVM {
JNIEnv *env;
JavaVM *jvm;
};
void invoke_class(JNIEnv* env);
void *jvmThreads(void* myJvm) {
struct JVM *myJvmPtr = (struct JVM*) myJvm;
JavaVM *jvmPtr = myJvmPtr -> jvm;
JNIEnv *env = myJvmPtr -> env;
pthread_mutex_lock (&mutexjvm);
printf("I will call JVM\n");
(*jvmPtr)->AttachCurrentThread(jvmPtr, (void**) &(env), NULL);
invoke_class( env );
(*jvmPtr)->DetachCurrentThread(jvmPtr);
pthread_mutex_unlock (&mutexjvm);
pthread_exit(NULL);
}
JNIEnv* create_vm(struct JVM *jvm)
{
JNIEnv* env;
JavaVMInitArgs vm_args;
JavaVMOption options;
options.optionString = "-Djava.class.path=./";
vm_args.options = &options;
vm_args.ignoreUnrecognized = 0;
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
int status = JNI_CreateJavaVM(&jvm->jvm, (void**)&env, &vm_args);
if (status < 0 || !env)
printf("Error\n");
return env;
}
void invoke_class(JNIEnv* env)
{
jclass Main_class;
jmethodID fun_id;
Main_class = (*env)->FindClass(env, "Main");
fun_id = (*env)->GetStaticMethodID(env, Main_class, "fun", "()I");
(*env)->CallStaticIntMethod(env, Main_class, fun_id);
}
int main(int argc, char **argv)
{
struct JVM myJvm;
myJvm.env = create_vm(&myJvm);
if(myJvm.env == NULL)
return 1;
pthread_mutex_init(&mutexjvm, NULL);
for(int i=0; i<NUM_THREADS; i++){
pthread_create(&threads[i], NULL, jvmThreads, (void*) &myJvm);
pthread_join(threads[i], 0);
}
(*myJvm.jvm)->DestroyJavaVM(myJvm.jvm);
}
Main.java
public class Main {
public static void main(String[] args){
System.out.println("Hello, world");
}
public static int fun() {
System.out.println("From JVM");
return 0;
}
}
Makefile
all: Main.class main
Main.class: Main.java
javac Main.java
main.o: main.c
llvm-gcc -c main.c \
-I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/darwin/ \
main: main.o
ld -o main -L${JAVA_HOME}/jre/lib/server/ \
-ljvm \
-rpath ${JAVA_HOME}/jre/lib/server \
-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk \
-demangle -dynamic -arch x86_64 \
-macosx_version_min 10.12.0 \
-lSystem \
-rpath ${JAVA_HOME}/jre/lib/server/ \
main.o
clean:
rm -f Main.class main main.o
Once you run the code, you get following result:
./main
I will call JVM
From JVM
I will call JVM
From JVM
I will call JVM
From JVM
I will call JVM
From JVM
I will call JVM
From JVM
I will call JVM
From JVM
I'm trying to implement a java wrapper for RCSwitch in a Raspberry Pi. It works fine until the grabbing method reaches the 80th iteration. Then it slows down and I can't figure out why. It needs more than 5 minutes to return with a value.
I tried to figure out the problem, but I'm not out of memory, the raspberry still has more then 300mega. In spite ot this, I tried to run the JVM with the following parameter:-Xms5m -Xmx5m but the program still slowed down at the 80th iteration so I think its not a memory problem. My sender still sends the value, because if I restart the program it's working again until the 80th iteration, so it's not the lack of input data.
Here is the java part of the code:
public class RCSwitchWrapper {
public native int recievedValue(int PIN);
static{System.loadLibrary("RCSwitchWrapper");}
public static void main(String[] args){
RCSwitchWrapper wrapper = new RCSwitchWrapper();
int counter=0;
while(true){
counter++;
int grabbedData = wrapper.recievedValue(2);
System.out.println(counter+" grabbed data: "+grabbedData);
}
}
}
The C++ part of the code:
#include "RCSwitch.h"
#include "RCSwitchWrapper.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
RCSwitch mySwitch;
JNIEXPORT jint JNICALL Java_RCSwitchWrapper_recieveValue(JNIEnv *env, jobject obj,jint PIN){
if(wiringPiSetup()==-1){
printf("wiringpi error \n");
return 0;
}
mySwitch = RCSwitch();
mySwitch.enableReceive(PIN);
while(1){
if(mySwitch.available()){
int value = mySwitch.getReceivedValue();
return value;
}
mySwitch.resetAvailable();
return(-1);
}
}
Now I'm confused and can't think a solution.
Thanks in advance.
The Point:
I want to call a C/C++ function from Java.
What I do:
I am able to generate a .h file using the "javah" program. It correctly spits out my header file. Perfect. I added two .c files that include this header file, where only one of which implements the function. The second one is a completely empty .c file due to a bug in the Android NDK build system. All fine and dandy so far.
I use the Android NDK "ndk-build" script to generate my .so files for multiple different platforms. Again, works perfectly.
I added these library files (in their respective folders) to the jniLibs folder in my Android Studio Project. Gradle sees them, and correctly adds them to my .apk file at build-time.
In my app source code, I use static { System.loadLibrary("testLib"); }. (Yes that's the correct filename). And it loads it successfully no issue.
The Problem:
As soon as I try to call the native function (defined in java and implemented in C++), I get the following exception:
java.lang.UnsatisfiedLinkError: Native method not found:
com.example.nativeapp.MainActivity.testNativeMethod:()Ljava/lang/String;"
This is where things get weird :/: I compile successfully with NDK, build successfully with Gradle, and "loadLibrary" successfully with Java in my application code. But when simply calling the function "testNativeMethod();", that's when I get the runtime exception and the application Crashes.
Here is my "javah" generated header file:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_nativeapp_MainActivity */
#ifndef _Included_com_example_nativeapp_MainActivity
#define _Included_com_example_nativeapp_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_nativeapp_MainActivity_MODE_PRIVATE
#define com_example_nativeapp_MainActivity_MODE_PRIVATE 0L
#undef com_example_nativeapp_MainActivity_MODE_WORLD_READABLE
#define com_example_nativeapp_MainActivity_MODE_WORLD_READABLE 1L
#undef com_example_nativeapp_MainActivity_MODE_WORLD_WRITEABLE
#define com_example_nativeapp_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef com_example_nativeapp_MainActivity_MODE_APPEND
#define com_example_nativeapp_MainActivity_MODE_APPEND 32768L
#undef com_example_nativeapp_MainActivity_MODE_MULTI_PROCESS
#define com_example_nativeapp_MainActivity_MODE_MULTI_PROCESS 4L
#undef com_example_nativeapp_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_example_nativeapp_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_example_nativeapp_MainActivity_BIND_AUTO_CREATE
#define com_example_nativeapp_MainActivity_BIND_AUTO_CREATE 1L
#undef com_example_nativeapp_MainActivity_BIND_DEBUG_UNBIND
#define com_example_nativeapp_MainActivity_BIND_DEBUG_UNBIND 2L
#undef com_example_nativeapp_MainActivity_BIND_NOT_FOREGROUND
#define com_example_nativeapp_MainActivity_BIND_NOT_FOREGROUND 4L
#undef com_example_nativeapp_MainActivity_BIND_ABOVE_CLIENT
#define com_example_nativeapp_MainActivity_BIND_ABOVE_CLIENT 8L
#undef com_example_nativeapp_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_example_nativeapp_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_example_nativeapp_MainActivity_BIND_WAIVE_PRIORITY
#define com_example_nativeapp_MainActivity_BIND_WAIVE_PRIORITY 32L
#undef com_example_nativeapp_MainActivity_BIND_IMPORTANT
#define com_example_nativeapp_MainActivity_BIND_IMPORTANT 64L
#undef com_example_nativeapp_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_example_nativeapp_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_example_nativeapp_MainActivity_CONTEXT_INCLUDE_CODE
#define com_example_nativeapp_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_example_nativeapp_MainActivity_CONTEXT_IGNORE_SECURITY
#define com_example_nativeapp_MainActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_example_nativeapp_MainActivity_CONTEXT_RESTRICTED
#define com_example_nativeapp_MainActivity_CONTEXT_RESTRICTED 4L
#undef com_example_nativeapp_MainActivity_RESULT_CANCELED
#define com_example_nativeapp_MainActivity_RESULT_CANCELED 0L
#undef com_example_nativeapp_MainActivity_RESULT_OK
#define com_example_nativeapp_MainActivity_RESULT_OK -1L
#undef com_example_nativeapp_MainActivity_RESULT_FIRST_USER
#define com_example_nativeapp_MainActivity_RESULT_FIRST_USER 1L
#undef com_example_nativeapp_MainActivity_DEFAULT_KEYS_DISABLE
#define com_example_nativeapp_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_example_nativeapp_MainActivity_DEFAULT_KEYS_DIALER
#define com_example_nativeapp_MainActivity_DEFAULT_KEYS_DIALER 1L
#undef com_example_nativeapp_MainActivity_DEFAULT_KEYS_SHORTCUT
#define com_example_nativeapp_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_example_nativeapp_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_example_nativeapp_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_example_nativeapp_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_example_nativeapp_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
/*
* Class: com_example_nativeapp_MainActivity
* Method: testNativeMethod
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_nativeapp_MainActivity_testNativeMethod
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Here is my .c implementation file:
#include "com_example_nativeapp_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_example_nativeapp_MainActivity_testNativeMethod(JNIEnv* environment, jobject obj)
{
return ( *env )->NewStringUTF(env, "HELLO FROM C Native!");
}
And last but not least, here is my .java Application file:
package com.example.nativeapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class MainActivity extends Activity
{
static { System.loadLibrary("testLib"); }
private TextView mDebugText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDebugText = (TextView)findViewById(R.id.debug_text);
// Here is where my native function call takes place. Without this, the app does (NOT) crash.
mDebugText.setText(testNativeMethod());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public native String testNativeMethod();
}
Thanks in advance. This is definitely one of those punch the monitor types of problems.
Just a quick heads up:
I've tried this: https://www.youtube.com/watch?v=okLKfxfbz40 three times in a row following the steps perfectly and still resulted in failure.
Also, I've been reading around here on Stackoverflow and none of the problems match my case. They are all using opencv etc, I just want to make my own "Hello World" Android NDK library. And once again, thanks in advance.
Edited to fix formating issues for readability.
Fixed it.
The Fix:
I changed the main.c to a main.cpp file so I can use "extern "C"". That way I knew I was invoking the C compiler correctly.
Here's my new main.c file (now called main.cpp)(compare with OP source above^^^^^):
extern "C"
{
#include "com_example_nativeapp_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_example_nativeapp_MainActivity_testNativeMethod(JNIEnv* env, jobject obj)
{
return env->NewStringUTF("HELLO FROM C Native!");
}
}
OS X Lion still goes to sleep, even if programmatic mouse "wiggles" are being periodically issued from a Java Robot (this is a standard approach to keeping machines from going to sleep and is documented elsewhere in stackoverflow, and it worked for me prior to OS X Lion).
Can anyone suggest an alternative approach, which does not require permission escalation, of keeping the machine awake from a Java application?
((The fallback solution is obviously to change the Energy Saving preferences so that the machine never sleeps, but we'd like to be smarter than that because requiring the machine to stay awake is the exception rather than the rule)).
It turns out that it is no longer possible to do this with pure-Java hacks, and one must resort to implementing a JNI I/O listener, the code of which would contain something like
http://developer.apple.com/library/mac/#qa/qa1340/_index.html
An alternative, if you can tolerate calling a command line tool, is to call pmset noidle in a daemon thread.
Do you need to prevent display sleep or system sleep? If the latter, you can prevent system sleep with disk activity - e.g. read from or write to a file.
Hard disk activity does not prevent display sleep, but it does prevent
system sleep. It is not uncommon for the display to sleep before the
system goes to sleep if both types of sleep are set to occur after the
same length of inactivity.
http://support.apple.com/kb/ht1776
This answer points to Objective-C code that can be used to prevent sleep, using the UpdateSystemActivity call. Could you create a simple JNI wrapper on this which you could invoke as a native method from your Java code?
It also seems possible to disable and re-enable sleep using applescript. Could you invoke such a script using Runtime.exec() from your Java code?
Following JNI solution works for macOS 10.5 / GCC
I. Definition Java Native Interface
// File KalleInterface.java
public class KalleInterface
{
static
{
// java.library.path set to libKalleInterface.dylib
System.loadLibrary("KalleInterface");
}
public static native boolean preventSleep();
public static native boolean allowSleep();
}
II. Generate Equivalent C++ Interface
Assume compliled java class file is ./bin/KalleInterface.class
javah -jni -d "${PWD}" -classpath "${PWD}/bin" KalleInterface
generates a C++ header KalleInterface.h as
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class KalleInterface */
#ifndef _Included_KalleInterface
#define _Included_KalleInterface
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: KalleInterface
* Method: preventSleep
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_KalleInterface_preventSleep(JNIEnv *, jclass);
/*
* Class: KalleInterface
* Method: allowSleep
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_KalleInterface_allowSleep(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
III. Implement C++ Interface
#include "esc_util_KalleInterface.h"
#include <IOKit/pwr_mgt/IOPMLib.h>
// IOPMAssertionCreateWithName ...
// kIOPMAssertionTypeNoDisplaySleep prevents display sleep,
// kIOPMAssertionTypeNoIdleSleep prevents idle sleep
//reasonForActivity is a descriptive string used by the system whenever it needs
// to tell the user why the system is not sleeping. For example,
// "Mail Compacting Mailboxes" would be a useful string.
// IOPMAssertionDeclareUserActivity ...
// claims user activity
#ifdef __cplusplus
extern "C" {
#endif
CFStringRef reasonForActivity= CFSTR("User Activity Type");
// NOTE: IOPMAssertionCreateWithName limits the string to 128 characters.
IOPMAssertionID assertionID;
static bool active = false;
/*
* Class: KalleInterface
* Method: preventSleep
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_esc_util_KalleInterface_preventSleep(JNIEnv*, jclass)
{
IOReturn success = 0;
if (active)
{
return (jboolean)true;
}
//success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, reasonForActivity, &assertionID);
//success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &assertionID);
success = IOPMAssertionDeclareUserActivity(reasonForActivity, kIOPMUserActiveLocal, &assertionID);
active =(success == kIOReturnSuccess);
return (jboolean)active;
//Add the work you need to do without
// the system sleeping here.
}
/*
* Class: KalleInterface
* Method: allowSleep
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_esc_util_KalleInterface_allowSleep(JNIEnv *, jclass)
{
IOReturn success = 0;
if (!active)
{
return (jboolean)true;
}
success = IOPMAssertionRelease(assertionID);
active = !(success == kIOReturnSuccess);
//The system will be able to sleep again.
return (jboolean)(!active);
}
#ifdef __cplusplus
}
#endif
IV. Build Shared Library
Command line steps for building libKalleInterface.dylib are
g++ -c -fPIC -I ${JAVA_HOME}/include -I ${JAVA_HOME}/include/darwin -o KalleInterfaceCPP.o KalleInterfaceCPP.cpp
g++ -dynamiclib -framework CoreFoundation -framework IOKit -o libKalleInterface.dylib KalleInterfaceCPP.o -lc
V. Test Class
// File KalleTest.java
public class KalleTest
{
public static void main(String...args)
{
boolean ok1 = KalleInterface.preventSleep();
System.out.println(ok1);
try
{
Thread.sleep(60*10*1000);
}
catch (Exception x)
{
x.printStackTrace();
}
boolean ok2 = KalleInterface.allowSleep();
System.out.println(ok2);
}
}
Assuming compiled class is ./bin/KalleTest.class and shared library is ./libKalleInterface.dylib, test is invoked by
java -Djava.library.path=${PWD} -classpath ./bin KalleTest
Expected behaviour: Mac remains active for 10 minutes, each of preventSleep(), allowSleep() produce result/output true.