Not able to set LD_LIBRARY_PATH for Java process
Dunes answer solves your problem, but I would strongly suggest a different approach in this particular case. Instead of relying on a shell to set the environment arguments, you should do this in your Java code. This way you don't need to know which shells exist on the system and what their language is, it will just work on all platforms.
To do this, you can use the Runtime.exec(String[] cmd, String[] environment)
overload (javadoc). As the second parameter you can pass an array which contains all the environment variables the subprocess will see.
A little bit nicer even is the ProcessBuilder
API:
ProcessBuilder pb = new ProcessBuilder("executable.so");
Map<String, String> env = pb.environment();
env.put("LD_LIBRARY_PATH", "/proj/something");
Process javap = pb.start();
javap.waitFor();
This way, the subprocess will inherit all environment variables from the Java process, and additionally have the LD_LIBRARY_PATH
variable set.
How to set a unix dynamic library path (LD_LIBRARY_PATH) in Java?
See my answer to another question. The best way is to not use an external shell to set the environment variable (your code doesn't work because it will not set the variable globally, only for the bash process), but to set the variable from within Java. Much easier and it works (and on all platforms, regardless of which shell is installed).
Setting of the LD_LIBRARY_PATH within a Java application
LD_LIBRARY_PATH is an environment varable, not a system properety. As tehre is no System.setEnv method I doubt you can do what you seek for. Read here: How do I set environment variables from Java?
What is LD_LIBRARY_PATH and how to use it?
Typically you must set java.library.path
on the JVM's command line:
java -Djava.library.path=/path/to/my/dll -cp /my/classpath/goes/here MainClass
Set LD_LIBRARY_PATH or java.library.path for YARN / Hadoop2 Jobs
Short Answer: in your mapred-site.xml put the following
<property>
<name>mapred.child.java.opts</name>
<value>-Djava.library.path=$PATH_TO_NATIVE_LIBS</value>
</property>
Explanation:
The Job/Applications aren't executed by yarn rather than by a mapred (map/reduce) container, whoose configuration is controlled by the mapred-site.xml file. Specifying custom java parameters there causes that actual workers to spin with the correct path
How to add .so file to the java.library.path in Linux
Add the containing directory to LD_LIBRARY_PATH
before launching the application
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/some/pathOfContainingDirectory
Use java -XshowSettings:properties
to show the java.library.path (and others) value.
LD_LIBRARY_PATH ignored on Android sometimes
Here is a simple wrapper I wrote about:
#include <android/log.h>
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
typedef int (*main_t)(int argc, char** argv);
static int help(const char* argv0)
{
printf("%s: simple wrapper to work around LD_LIBRARY_PATH\n\n", argv0);
printf("Args: executable, list all the libraries you need to load in dependency order, executable again, optional parameters\n");
printf("example: %s /data/local/ttte /data/data/app/com.testwrapper/lib/ttt.so /data/local/ttte 12345\n", argv0);
printf("Note: the executable should be built with CFLAGS=\"-fPIC -pie\", LDFLAGS=\"-rdynamic\"\n");
return -1;
}
int main(int argc, char** argv)
{
int rc, nlibs;
void *dl_handle;
if (argc < 2)
{
return help(argv[0]);
}
__android_log_print(ANDROID_LOG_DEBUG, "wrapper", "running '%s'", argv[1]);
for (nlibs = 2; ; nlibs++)
{
if (nlibs >= argc)
{
return help(argv[0]);
}
__android_log_print(ANDROID_LOG_DEBUG, "wrapper", "loading '%s'", argv[nlibs]);
dl_handle = dlopen(argv[nlibs], 0); // do not keep the handle, except for the last
__android_log_print(ANDROID_LOG_DEBUG, "wrapper", "loaded '%s' -> %p", argv[nlibs], dl_handle);
if (strcmp(argv[1], argv[nlibs]) == 0)
{
break;
}
}
main_t pmain = (main_t)dlsym(dl_handle, "main");
__android_log_print(ANDROID_LOG_DEBUG, "wrapper", "found '%s' -> %p", "main", pmain);
rc = pmain(argc - nlibs, argv + nlibs);
// we are exiting the process anyway, don't need to clean the handles actually
// __android_log_print(3, "wrapper", "closing '%s'", argv[1]);
// dlclose(dl_handle);
return 0;
}
To keep it readable, I drop most of error handling, unessential cleanup, and handling of special cases.
Android.mk
for this executable:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := wrapper
LOCAL_SRC_FILES := wrapper/main.c
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
Note that you must take care of deployment: packaging this wrapper
into the APK, extraction to some local path (never to USB storage or to /sdcard
!), marking it as executable (chmod 777
).
These are the additional parameters you must supply when you build the executables you run through the wrapper
. If you use ndk-build
to build them, it looks as follows:
LOCAL_C_FLAGS += -fPIC -pie
LOCAL_LDFLAGS += -rdynamic
Note that you don't need to chmod
for these executables anymore. Another trick: you can build the secondary executables into shared libraries, and the same wrapper will continue to work! This saves the trouble of deployment of these binaries. NDK and Android build will deliver them safely through libs/armeabi of the APK to your app's lib directory automagically.
Update
There seems to be a much easier solution, using the ProcessBuilder with modified environment: https://stackoverflow.com/a/8962189/192373.
Related Topics
Image Encryption/Decryption Using Aes256 Symmetric Block Ciphers
How to Convert a Color Integer to a Hex String in Android
Error:(23, 17) Failed to Resolve: Junit:Junit:4.12
Java.Lang.Numberformatexception: Invalid Double: " "
Limit Decimal Places in Android Edittext
How to Whitelist App in Doze Mode Android 6.0
How to Use Intent.Flag_Activity_Clear_Top to Clear the Activity Stack
How to Programmatically Set Drawableleft on Android Button
Android Download Binary File Problems
How to Get Android Wifi Scan Results into a List
Getting Frames from Video Image in Android
How to Use the Legacy Apache Http Client on Android Marshmallow
Error:Execution Failed for Task ':App:Dexdebug'. Com.Android.Ide.Common.Process.Processexception
Using Singleton Design Pattern for SQLitedatabase