avian 是一个小型的Java虚拟机,实现了Java的部分基本功能。具体API可以看 这里 。不过这个虚拟机只提供源代码,需要你在linux、MSYS或Cygwin下编译好后才能使用,我在MSYS下尝试了一下,总是报错,最后只好转到Ubuntu下面才成功编译。
编译过程很简单,只要遵照他的提示就可以了,不过事先肯定是要装好GCC和JDK的(推荐OpenJDK),目标为win32平台时,还需要win32的头文件和库,可以从它的git站点
下载 。 下载后解压到avian目录的上一级目录。
1 | $ export JAVA_HOME=/usr/ local /java |
2 | $ make platform=windows arch=i386 |
make后面的平台和架构都有其他的选项,比如linux/darwin x86_64等,具体参数可以看
这里 ,编译完成后在build目录下应该有个windows-i386文件夹,里面就是编译好的虚拟机和示例程序。
使用avian的好处就在于它很小,可以直接转为本地程序,下面就是在ubuntu的mingw和avian环境下,编译JAVA程序并且将其转化为可以在Window上运行的普通程序
avian 小型JAVA虚拟机(window-i386版本)
mingw 交叉编译环境
步骤1
建立项目目录${project},复制必要文件。
3 | ar x ../windows-i386/libavian.a |
4 | cp ../windows-i386/classpath.jar boot.jar |
步骤2
这一步在eclipse里面完成比较方便,编写JAVA源文件${源代码},直接把JRE替换为avian,再加入其他包如SWT等,统一用eclipse编译,直接导出为JAR包,导出时将其他JAR也解开。
步骤3
把上面生成的 JAR 包 转为目标文件。
1 | ../windows-i386/binaryToObject boot.jar boot-jar.o _binary_boot_jar_start _binary_boot_jar_end windows i386 |
步骤4
建立main.cpp文件
08 | #if (defined __MINGW32__) || (defined _MSC_VER) |
09 | # define EXPORT __declspec(dllexport) |
11 | # define EXPORT __attribute__ ((visibility("default"))) |
14 | #if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER)) |
15 | # define SYMBOL(x) binary_boot_jar_##x |
17 | # define SYMBOL(x) _binary_boot_jar_##x |
22 | extern const uint8_t SYMBOL(start)[]; |
23 | extern const uint8_t SYMBOL(end)[]; |
26 | bootJar(unsigned* size) |
28 | *size = SYMBOL(end) - SYMBOL(start); |
35 | main( int ac, const char ** av) |
37 | JavaVMInitArgs vmArgs; |
38 | vmArgs.version = JNI_VERSION_1_2; |
40 | vmArgs.ignoreUnrecognized = JNI_TRUE; |
42 | JavaVMOption options[vmArgs.nOptions]; |
43 | vmArgs.options = options; |
45 | options[0].optionString = const_cast < char *>( "-Xbootclasspath:[bootJar]" ); |
49 | JNI_CreateJavaVM(&vm, &env, &vmArgs); |
50 | JNIEnv* e = static_cast <JNIEnv*>(env); |
52 | jclass c = e->FindClass( "Hello" ); |
53 | jmethodID m = e->GetStaticMethodID(c, "main" , "([Ljava/lang/String;)V" ); |
54 | if (not e->ExceptionCheck()) { |
55 | jclass stringClass = e->FindClass( "java/lang/String" ); |
56 | if (not e->ExceptionCheck()) { |
57 | jobjectArray a = e->NewObjectArray(ac-1, stringClass, 0); |
58 | if (not e->ExceptionCheck()) { |
59 | for ( int i = 1; i < ac; ++i) { |
60 | e->SetObjectArrayElement(a, i-1, e->NewStringUTF(av[i])); |
63 | e->CallStaticVoidMethod(c, m, a); |
70 | if (e->ExceptionCheck()) { |
72 | e->ExceptionDescribe(); |
步骤5
编译和链接,下面的程序名称如msvc++都是我取的别名,因为原名称实在太长了,应该是i586-mingw32msvc-c++,不同的mingw版本可能会有所不同,${project}就是你工程的名称。
1 | export JAVA_HOME=/usr/lib/jvm/java-6-openjdk |
2 | msvc++ -I$JAVA_HOME/include -I$JAVA_HOME/include/win32 -D_JNI_IMPLEMENTATION_ -c main.cpp -o main.o |
3 | msdlltool -z ${project}.def *.o |
4 | msdlltool -d ${project}.def -e ${project}.exp |
5 | msvc++ ${project}.exp *.o -L../win32/lib -lmingwthrd -lm -lz -lws2_32 -mwindows -mconsole -o ${project}.exe |
6 | msstrip --strip-all ${project}.exe |
最后 把{project}.exe复制回Windows即可,在只加入SWT的情况下,程序的大小是2M多