Hi Evandro,
Based on the code you provided, it looks like you've used
https://github.com/ReadyTalk/avian#embedding as a starting point.
However, you left out an important part:
extern "C" {
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
EXPORT const uint8_t*
bootJar(size_t* size)
{
*size = SYMBOL(end) - SYMBOL(start);
return SYMBOL(start);
}
} // extern "C"
That ensures there is a bootJar function from which Avian can load the
boot jar. That's what makes this line work:
options[0].optionString = const_cast<char*>("-Xbootclasspath:[bootJar]");
I've modified your code as follows:
#include "stdint.h"
#include "jni.h"
#include "stdlib.h"
#include "lua.hpp"
#define EXPORT __attribute__ ((visibility("default"))) \
__attribute__ ((used))
#define SYMBOL(x) _binary_boot_jar_##x
extern "C" {
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
EXPORT const uint8_t*
bootJar(size_t* size)
{
*size = SYMBOL(end) - SYMBOL(start);
return SYMBOL(start);
}
} // extern "C"
extern "C" void __cxa_pure_virtual(void) { abort(); }
namespace {
int openVM(lua_State* state) {
// Initialising VM options
JavaVMInitArgs vmArgs;
vmArgs.version = JNI_VERSION_1_2;
vmArgs.nOptions = 2;
vmArgs.ignoreUnrecognized = JNI_TRUE;
// Build options array
JavaVMOption options[vmArgs.nOptions];
vmArgs.options = options;
options[0].optionString = const_cast<char*>("-Xbootclasspath:[bootJar]");
char *optbootstrap = const_cast<char*>("-Davian.bootstrap=avian.so");
options[1].optionString = optbootstrap;
printf("Option: %s\n", optbootstrap);
// Creates JVM
JavaVM* vm;
void* env;
JNI_CreateJavaVM(&vm, &env, &vmArgs);
JNIEnv* e = static_cast<JNIEnv*>(env);
int exitCode = 0;
{
jclass c = e->FindClass("java/lang/Class");
}
jclass c = e->FindClass("Hello");
if (not e->ExceptionCheck()) {
jmethodID m = e->GetStaticMethodID(c, "main", "([Ljava/lang/String;)V");
if (not e->ExceptionCheck()) {
jclass stringClass = e->FindClass("java/lang/String");
if (not e->ExceptionCheck()) {
jobjectArray a = e->NewObjectArray(0, stringClass, 0);
if (not e->ExceptionCheck()) {
e->CallStaticVoidMethod(c, m, a);
}
}
}
}
if (e->ExceptionCheck()) {
exitCode = -1;
e->ExceptionDescribe();
} else {
printf("success!");
}
vm->DestroyJavaVM();
return exitCode;
}
} // namespace
extern "C" int luaopen_avian(lua_State* state) {
printf("luaopen_avian(lua_State* state)\n");
openVM(state);
return 0;
}
(I put that in a file called main.cpp)
Then I built everything like this:
ar x ~/p/avian/build/macosx-x86_64/libavian.a
cp ~/p/avian/build/macosx-x86_64/classpath.jar boot.jar
cat >Hello.java <<EOF
public class Hello {
public static void main(String[] args) {
System.out.println("hello, world!");
}
}
EOF
javac -bootclasspath boot.jar Hello.java
jar u0f boot.jar Hello.class
~/p/avian/build/macosx-x86_64/binaryToObject/binaryToObject boot.jar
boot-jar.o _binary_boot_jar_start _binary_boot_jar_end macosx x86_64
g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin -I
/Users/dicej/Downloads/lua-5.1.5/etc/ -I
/Users/dicej/Downloads/lua-5.1.5/src/ -D_JNI_IMPLEMENTATION_ -c
main.cpp -o main.o
g++ -shared *.o -ldl -lpthread -lz -o avian.so -framework CoreFoundation
Then I ran it, and it seemed to work:
~/Downloads/lua-5.1.5/src/lua -l avian