如何将Java代码打包为exe文件
来源:优易学  2011-12-17 15:45:41   【优易学:中国教育考试门户网】   资料下载   IT书店

  现在有很多的工具将Java代码打包为exe文件,执行时不需要再编写批处理文件,或者在命令行输入长长的classpath信息,为用户使用提供了很大的方便。这也是很多商业软件常常使用的方法。

  将Java代码打包为exe文件,一般需要两个步骤:

  1.       编写本地代码,创建虚拟机,加载并执行Main Class。

  2.       将Java代码打包为jar文件,并与本地代码exe文件合并。

  下面的代码,会加载jvm.dll,并调用JNI_CreateJavaVM导出函数创建Java虚拟机,得到JNIEnv指针,然后调用 FindClass查找Main Class,之后调用GetStaticMethodID方法得到main方法,并执行main方法。代码如下:

  #include <windows.h>

  #include <jni.h>

  //#pragma comment( linker, "/subsystem:"console" /entry:"mainCRTStartup"" )

  #pragma comment( linker, "/subsystem:"windows" /entry:"WinMainCRTStartup"" )

  typedef jint (JNICALL *JNICREATEPROC)(JavaVM **, void **, void *);

  bool setStream(JNIEnv *env, const char* pszFileName, const char* pszMethod);

  //启动java虚拟机方法

  //bool main(int argc,char *argv[])

  int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)

  ...{

  //jvm动态库的路径

  const char szJvmPath[] = "d:\jdk1.5.0_07\jre\bin\server\jvm.dll";

  //java 虚拟机的启动参数,每个参数写一项,不能合在一起写

  int nOptionCount = 2;

  JavaVMOption options[2];

  options[1].optionString = "-Xmx256M";

  //设置classpath

  options[0].optionString = "-Djava.class.path=./Test.exe";

  JavaVMInitArgs vm_args;

  vm_args.version = JNI_VERSION_1_4;

  vm_args.options = options;

  vm_args.nOptions = nOptionCount;

  vm_args.ignoreUnrecognized = JNI_TRUE;

  //启动类,注意分割符是/,例如启动类test.JTest应该写成 test/JTest

  const char szStartClass[] = "com/primeton/test/TestClass";

  //启动方法,通常是main函数,你也可以设定成其他函数

  const char szStartMethod[] = "main";

  //重导向文件

  const char szStdoutFileName[] = "stdout.txt";

  const char szStderrFileName[] = "stderr.txt";

  //java程序的命令行参数

  int nParamCount = 2;

  const char *szParams[2] = ...{"arg1","arg2"};

  //加载JVM。

  HINSTANCE jvmDll = LoadLibrary(szJvmPath);

  if (jvmDll == NULL)

  ...{

  printf("加载JVM动态库错误。%l", ::GetLastError());

  return false;

  }

  //查找JNI_CreateJavaVM过程。

  JNICREATEPROC jvmCreateProc = (JNICREATEPROC)GetProcAddress(jvmDll, "JNI_CreateJavaVM");

  if (jvmCreateProc == NULL)

  ...{

  FreeLibrary(jvmDll);

  printf("查找JNI_CreateJavaVM过程错误。%l", ::GetLastError());

  return false;

  }

  //创建JVM。

  JNIEnv *env;

  JavaVM *jvm;

  jint r = (jvmCreateProc)(&jvm, (void **)&env, &vm_args);

  if (r < 0 || jvm == NULL || env == NULL)

  ...{

  FreeLibrary(jvmDll);

  printf( "创建JVM发生错误。");

  return false;

  }

  //重导向stdout, stderr到输出文件

  if (!setStream(env, szStdoutFileName, "setOut"))

  ...{

  printf("设置stdout输出文件失败");

  return false;

  }

  if (!setStream(env, szStderrFileName, "setErr"))

  ...{

  printf("设置stderr输出文件失败");

  return false;

  }

  //加载启动类。

  jclass serviceClass = env->FindClass(szStartClass);

  if (env->ExceptionCheck() == JNI_TRUE || serviceClass == NULL)

  ...{

  env->ExceptionDescribe();

  env->ExceptionClear();

  FreeLibrary(jvmDll);

  printf("加载启动类失败。");

  return false;

  }

  //启动方法

  jmethodID mid = env->GetStaticMethodID(serviceClass, szStartMethod , "([Ljava/lang/String;)V");

  if (env->ExceptionCheck() == JNI_TRUE || mid == NULL)

  ...{

  env->ExceptionDescribe();

  env->ExceptionClear();

  FreeLibrary(jvmDll);

  printf("查找启动方法失败。");

  return false;

  }

  //查找String类。

  jclass stringClass = env->FindClass("java/lang/String");

  if (env->ExceptionCheck() == JNI_TRUE || stringClass == NULL)

  ...{

  env->ExceptionDescribe();

  env->ExceptionClear();

  FreeLibrary(jvmDll);

  printf("查找String类失败。");

  return false;

  }

[1] [2] [3] 下一页

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训