Creating JVM using JNI functions

1,407 views
Skip to first unread message

Ilya Berezhnoy

unread,
Jul 20, 2018, 10:51:04 AM7/20/18
to android-ndk
Hi everyone,

I try to find out is it possible to create jvm machine to call java code in native application (c++).
In my project i use gradle and cmake for building. 

here is a part of configuration

android {
 compileSdkVersion
27
 defaultConfig
{
 applicationId
"com.mycomp.vpntuner"
 minSdkVersion
24
 targetSdkVersion
27
 versionCode
1
 versionName
"1.0"
 testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"

 externalNativeBuild
{
 cmake
{
 arguments
"-DANDROID_STL=c++_shared"
 cppFlags
"-std=c++14 -fexceptions"
 
}
 
}

 
}
 buildTypes
{
 release
{
 minifyEnabled
false
 proguardFiles getDefaultProguardFile
('proguard-android.txt'), 'proguard-rules.pro'
 
}
 debug
{
 jniDebuggable
true
 
}
 
}
 externalNativeBuild
{
 cmake
{
 path
"CMakeLists.txt"
 
}
 
}
 productFlavors
{
 
}
 compileOptions
{
 sourceCompatibility
JavaVersion.VERSION_1_8
 targetCompatibility
JavaVersion.VERSION_1_8
 
}
}


and a function to create VM:

JavaVM* javaVM = NULL;
 
JNIEnv* jEnv = NULL;

 
JavaVMOption opt[1];
 opt
[0].optionString = "-Djava.class.path=./";
 
JavaVMInitArgs args;
 args
.version = JNI_VERSION_1_6;
 args
.options = opt;
 args
.nOptions = 1;
 args
.ignoreUnrecognized = JNI_FALSE;

 
void *libdvm_dso = dlopen("libart.so", RTLD_NOW);
 
if(!libdvm_dso )
 
{
 printf
("error to load libart.so library\n");
 
return 1;
 
}
 
void *libandroid_runtime_dso = dlopen("libandroid_runtime.so", RTLD_NOW);
 
if(!libandroid_runtime_dso)
 
{
 printf
("error to load libandroid_runtime.so library\n");
 
return 1;
 
}
 JNI_CreateJavaVM_t JNI_CreateJavaVM
= NULL;
 JNI_CreateJavaVM
= (JNI_CreateJavaVM_t) dlsym(libdvm_dso, "JNI_CreateJavaVM");
 
if(!JNI_CreateJavaVM)
 
{
 printf
("error: JNI_CreateJavaVM is not found\n");
 
return 2;
 
}
 printf
("JNI_CreateJavaVM is linked!\n");
// registerNatives_t registerNatives;
// registerNatives = (registerNatives_t) dlsym(libandroid_runtime_dso, "Java_com_android_internal_util_WithFramework_registerNatives");
// if(!registerNatives)
// {
// printf("error: registerNatives is not found\n");
// return 3;
// }
// printf("registerNatives is linked!\n");
 
int rv = JNI_CreateJavaVM(&javaVM, &jEnv, &args);
 
if (rv < 0)
 
{
 printf
("Unable to Launch JVM %d\n", rv);
 
return 4;
 
}
 printf
("jvm is running!\n");

// if(!registerNatives(*p_env, 0))
// {
// printf("error to register natives\n");
// return 5;
// }
// printf("env is reg!\n");

so, the app is fault when JNI_CreateJavaVM is calling with SIGABRT signal.
I will be grateful for any help!

Philippe Simons

unread,
Jul 20, 2018, 12:29:39 PM7/20/18
to android-ndk
but but...
why would you want to create a JVM, when you application is already running in a JVM ?

anyway, I'm pretty sure that's not possible

Philippe

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To post to this group, send email to andro...@googlegroups.com.
Visit this group at https://groups.google.com/group/android-ndk.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/8f183b2f-712b-47b3-892b-ed721aa44d54%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andrew Esh

unread,
Jul 20, 2018, 1:34:33 PM7/20/18
to android-ndk

Dan Albert

unread,
Jul 20, 2018, 1:49:22 PM7/20/18
to android-ndk
In which case you should be using native_app_glue. The sample is a little convoluted, but the JavaVM is available as app->activity->vm (where app is the android_app struct that is passed to android_main): https://github.com/googlesamples/android-ndk/blob/master/native-activity/app/src/main/cpp/main.cpp#L273

Philippe Simons

unread,
Jul 20, 2018, 2:01:12 PM7/20/18
to android-ndk
NativeActivty are still running in a JVM (it's a Java class btw)
on Android, every application process is forked from the zygote, which is a pre warmed-up virtual machine.
You can't escape that.

Chris Browet

unread,
Jul 21, 2018, 2:21:59 PM7/21/18
to android-ndk
I bet the OP wants to run some Oracle Java bytecode inside Android.

That won't work. Android is using the java language, but the VM/bytecode is unrelated to J2SE or J2ME.
If you want to do that, you'd need to bundle your own compatible java vm.

Ilya Berezhnoy

unread,
Jul 21, 2018, 2:21:59 PM7/21/18
to android-ndk
Hi, Phillipe.

I guess I should say why i try to do it. 
So, we have an app written on c++ and successfully build and run on almost all popular linux distributives (Ubuntu, Fedora, etc). Our current goal is to port this app to android OS. while making this task i faced a problem how to build vpn tunnels on adnoid OS (we conider only non-rooted devices) and i found only one way. This way is to use VpnService class, providing API for tunnel building. The case i try to realise is to create vm when our app is started and call VpnService methods when we need to manage vpn tunnels (create interfaces and so on).
In our project we use openvpn3 client library which requires to redefine TunBuilderBase class for OS providing special API for tunnel building.
Now my android solution consists of 2 projects. First is UI written on java and the seccond is our native app beilng built for each platform(arm, eabi, etc). So, my idea is to run native app as service each time Android OS is started and UI is run by user when it's necessary to change setings or state of the service.  

пятница, 20 июля 2018 г., 21:01:12 UTC+3 пользователь Philippe Simons написал:

Ilya Berezhnoy

unread,
Jul 21, 2018, 2:21:59 PM7/21/18
to android-ndk
Do i understand you correctly what any app (even plain native app) is run inside vm? 


пятница, 20 июля 2018 г., 21:01:12 UTC+3 пользователь Philippe Simons написал:
NativeActivty are still running in a JVM (it's a Java class btw)

Dan Albert

unread,
Jul 21, 2018, 2:54:40 PM7/21/18
to android-ndk
Yes, every Android app is part of a Java process.

Chris Browet

unread,
Jul 22, 2018, 10:28:58 AM7/22/18
to android-ndk
VPnService is service. You create your own implementation, which is called by the system.
Not sure why you think you have to "create a vm".

What you should do is:
- Build the openvpn as a lib with NDK
- Create a native interface lib that will call the openvpn api, and a java class interfacing with this native lib through jni
- Use the Java interface class from your VpnService implementation, and possibly from your GUI activity

Alex Cohn

unread,
Aug 9, 2018, 1:46:30 PM8/9/18
to android-ndk
Reply all
Reply to author
Forward
0 new messages