文档章节

使用小型虚拟机avian将Java转为本地程序

antipro
 antipro
发布于 2012/05/12 09:57
字数 956
阅读 415
收藏 2
     avian是一个小型的Java虚拟机,实现了Java的部分基本功能。具体API可以看 这里。不过这个虚拟机只提供源代码,需要你在linux、MSYS或Cygwin下编译好后才能使用,我在MSYS下尝试了一下,总是报错,最后只好转到Ubuntu下面才成功编译。
    编译过程很简单,只要遵照他的提示就可以了,不过事先肯定是要装好GCC和JDK的(推荐OpenJDK),目标为win32平台时,还需要win32的头文件和库,可以从它的git站点 下载。 下载后解压到和avian源文件夹并列放置。
$ export JAVA_HOME=/usr/local/java #JDK位置
$ make platform=windows arch=i386
     make后面的平台和架构都有其他的选项,比如linux/darwin x86_64等,具体参数可以看 这里,编译完成后在build目录下应该有个windows-i386文件夹,里面就是编译好的虚拟机和示例程序。    
 
    使用avian的好处就在于它很小,可以直接转为本地程序,下面就是在ubuntu的mingw和avian环境下,编译JAVA程序并且将其转化为可以在Window上运行的普通程序
 
avian 小型JAVA虚拟机(window-i386版本)
mingw 交叉编译环境(现在更加新的可以采用ming-w64来编译)
 

步骤1

    建立项目目录${project},复制必要文件。
mkdir ${project}
cd ${project}
ar x ../windows-i386/libavian.a
cp ../windows-i386/classpath.jar boot.jar

步骤2

     这一步在eclipse里面完成比较方便,编写JAVA源文件${源代码},直接把JRE替换为avian,再加入其他包如SWT等,统一用eclipse编译,直接导出为JAR包,导出时将其他JAR也解开。
步骤3
    把上面生成的 JAR  包转为目标文件。

../windows-i386/binaryToObject boot.jar boot-jar.o _binary_boot_jar_start _binary_boot_jar_end windows i386

步骤4

    建立main.cpp文件
/*
* 调用Java类方法的模块
*/

#include "stdint.h"
#include "jni.h"

#if (defined __MINGW32__) || (defined _MSC_VER)
#  define EXPORT __declspec(dllexport)
#else
#  define EXPORT __attribute__ ((visibility("default")))
#endif

#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
#  define SYMBOL(x) binary_boot_jar_##x
#else
#  define SYMBOL(x) _binary_boot_jar_##x
#endif

extern "C" {

  extern const uint8_t SYMBOL(start)[];
  extern const uint8_t SYMBOL(end)[];

  EXPORT const uint8_t*
  bootJar(unsigned* size)
  {
    *size = SYMBOL(end) - SYMBOL(start);
    return SYMBOL(start);
  }

} // extern "C"

int
main(int ac, const char** av)
{
  JavaVMInitArgs vmArgs;
  vmArgs.version = JNI_VERSION_1_2;
  vmArgs.nOptions = 1;
  vmArgs.ignoreUnrecognized = JNI_TRUE;

  JavaVMOption options[vmArgs.nOptions];
  vmArgs.options = options;

  options[0].optionString = const_cast<char*>("-Xbootclasspath:[bootJar]");

  JavaVM* vm;
  void* env;
  JNI_CreateJavaVM(&vm, &env, &vmArgs);
  JNIEnv* e = static_cast<JNIEnv*>(env);

  jclass c = e->FindClass("Hello");//在这个地方替换包含main方法的类
  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(ac-1, stringClass, 0);
        if (not e->ExceptionCheck()) {
          for (int i = 1; i < ac; ++i) {
            e->SetObjectArrayElement(a, i-1, e->NewStringUTF(av[i]));
          }
          
          e->CallStaticVoidMethod(c, m, a);
        }
      }
    }
  }

  int exitCode = 0;
  if (e->ExceptionCheck()) {
    exitCode = -1;
    e->ExceptionDescribe();
  }

  vm->DestroyJavaVM();

  return exitCode;
}

步骤5

    编译和链接,下面的程序名称如msvc++都是我取的别名,因为原名称实在太长了,应该是i586-mingw32msvc-c++(或者也有可能会是i686-xxx等,不一定),不同的mingw版本可能会有所不同,${project}就是你工程的名称。
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk 
msvc++ -I$JAVA_HOME/include -I$JAVA_HOME/include/win32 -D_JNI_IMPLEMENTATION_ -c main.cpp -o main.o 
msdlltool -z ${project}.def *.o 
msdlltool -d ${project}.def -e ${project}.exp 
msvc++ ${project}.exp *.o -L../win32/lib -lmingwthrd -lm -lz -lws2_32 -mwindows -mconsole -o ${project}.exe      #去掉-mconsole后不会出现Console,直接显示GUI。
msstrip --strip-all ${project}.exe
其中java可以是更高的版本,最后把{project}.exe复制回Windows即可,在只加入SWT的情况下,程序的大小是2M多。
 

© 著作权归作者所有

antipro
粉丝 11
博文 7
码字总数 2956
作品 0
常州
高级程序员
私信 提问
加载中

评论(5)

antipro
antipro

引用来自“ZaneYoung”的评论

请问怎样让编译出来的swt程序隐藏cmd窗口啊?
去掉-mconsole后不会出现Console,直接显示GUI。
zaaack
zaaack
请问怎样让编译出来的swt程序隐藏cmd窗口啊?
jetma
jetma
win32的头文件现在已经移到了https://github.com/ReadyTalk/win32
jetma
jetma
写得很好
antipro
antipro
第一次写啊,编辑好麻烦。
Avian 0.7 发布,小型的 Java 虚拟机

Avian 0.7 包含很多 bug 修复,增加对 FreeBSD 的支持,改进对 Scala 的支持,增加使用 Android/Harmony 类库作为 OpenJDK 和 Avian 库的替代品。 Avian 是一个轻量级的 Java 虚拟机和类库,...

oschina
2013/07/11
2.6K
4
5 款用来开发 iOS 应用的 Java 开源工具

苹果iOS系统的封闭性一直广为其他语言(如Java)开发者诟病,但随着第三方工具的不断壮大,开发人员逐渐摆脱政策束缚,开始使用自己熟悉的语言来编写iOS本地应用,或将其他平台上的应用移植到...

oschina
2013/03/29
7.4K
15
Avian 1.0 发布,轻量级 Java 虚拟机

Avian 1.0 发布,Avian 是一个轻量级的 Java 虚拟机和类库,提供了 Java 特性的一个有用的子集,适合开发跨平台、自包容的应用程序。 该版本包含近一年的 bug 修复,提升对 OpenJDK 和 Andr...

oschina
2014/05/20
1K
0
用JavaScript编写一个Java虚拟机?谈谈哗众取宠的BicaVM

今日目睹某网络新闻,开篇明义便包含如下几行文字【程序员Artur Ventura,这位超级大牛,用JavaScript写了一个java虚拟机BicaVM】 继而再读,惊见其中“超级大牛”、“神人”等溢美之词不绝于...

兔bug
2011/11/24
18
1
用JavaScript编写一个Java虚拟机?谈谈哗众取宠的BicaVM

http://www.cnbeta.com/articles/163172.htm 感谢鹏凌三千的投递 新闻来源:原创 今日目睹某网络新闻,开篇明义便包含如下几行文字【程序员Artur Ventura,这位超级大牛,用JavaScript写了一个...

mallon
2011/11/23
1K
9

没有更多内容

加载失败,请刷新页面

加载更多

再一次生产 CPU 高负载排查实践

前言 前几日早上打开邮箱收到一封监控报警邮件:某某 ip 服务器 CPU 负载较高,请研发尽快排查解决,发送时间正好是凌晨。 其实早在去年我也处理过类似的问题,并记录下来:《一次生产 CPU ...

crossoverJie
19分钟前
1
0
Java的线程同步和并发问题示例

并发问题 多线程是一个非常强大的工具,它使我们能够更好地利用系统的资源,但我们需要在读取和写入多个线程共享的数据时特别小心。 当多个线程尝试同时读取和写入共享数据时,会出现两种类型...

hiuh
今天
4
0
Spring Boot 常用注解说明

实体类 @Entity (实体类注解) @Table(可指定表名) @Data(可缺省get/set) @Id(指定属性主键) @GeneratedValue(指定主键生成规则) @Transient(表示此数据不在数据库表里建立属性) ...

兜兜毛毛
今天
3
0
局域网能互相ping通,ubuntu虚拟机不能上外网

【问题】 桥接模式老是无法上网,查看本机IP发现被分配了一个私网地址,猜测应该是虚拟DHCP服务器没有打开,于是查看Ubuntu的网络配置: /etc/network/interfaces 发现没有dhcp配置的信息,只...

tahiti_aa
今天
2
0
以太坊助记词PHP开发包简介

以太坊助记词PHP开发包用来为PHP以太坊应用增加助记词和层级确定密钥支持能力。下载地址:以太坊助记词php开发包 。 1、开发包概述 以太坊助记词PHP开发包主要包括以下特性: 生成符合BIP39...

汇智网教程
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部