麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

打造個性化Java啟動器

2019-11-18 13:27:03
字體:
來源:轉載
供稿:網友

  主要內容:
  
  ________________________
  
   一、java程序的啟動過程
  
   二、Windows平臺的啟動器
  
   三、配置和使用
  
  ________________________
  
  對于普通用戶來說,Java最讓人不習慣的是程序的啟動過程;即使對于富有經驗的開發者,為了用默認的裝載器啟動Java程序,不得不編寫大量批命令、腳本文件,不得不在命令行環境下進行大量的復制/粘貼操作,也很輕易出現誤操作。
  
  用慣了Windows方便快捷的GUI,人們早就習慣了通過雙擊運行程序的方式。對于Java程序,要實現這個本機啟動功能就必須編寫定制的啟動器。用定制啟動器啟動Java程序不僅方便了最終用戶,而且使軟件作品看起來更專業。本文就以Windows平臺為例,介紹如何構造Java定制啟動器。
  打造個性化Java啟動器
  Java程序可以由任何本機運行的程序調用執行。所謂Java啟動器,就是一個專門用來啟動Java程序的本機執行程序。最常見的啟動器是Sun在Java Runtime Environment的/bin目錄中提供的啟動器,就Windows平臺而言,它們是java.exe和javaw.exe。前者運行時打開兩個窗口:一個是接收System.out/err和啟動器輸出的控制臺窗口,另一個是Java程序本身的窗口;javaw運行時不打開控制臺窗口。在J2SE/EE平臺中,虛擬機以動態庫的形式實現,也放在/bin目錄下。動態庫的名字在Windows中是java.dll,在Unix中是java.so。所謂“裝入虛擬機”,就是指裝入這個動態庫。
  
  提供給VM的參數可以通過兩種方式指定,或者是在啟動器的命令行參數中指定,或者通過定義相應的環境變量指定。只有一個參數例外——要啟動的類的名稱只能在啟動器的命令行參數中指定。雖然指定方式的多樣姓為人們各取所需帶來了方便,但不可否認地,它也正是許多混亂的根源。使用定制啟動器能夠完全避免這方面的問題。
  
  當VM結束啟動類的main()方法的運行,啟動器調用destroy()方法釋放各種資源并退出。應當注重的是,VM一旦開始運行,我們就不能再卸載它。對于Java啟動器來說,能否關閉VM無關緊要,因為啟動器會隨著Java程序的退出而退出;然而,對于嵌入了VM的本機應用,例如瀏覽器,這意味著有一塊內存被永久姓地占用,不能再收回。
  
  二、Windows平臺的啟動器
  
  搞清楚了Java程序的啟動過程,我們就可以開始編寫啟動器的代碼。下面這個啟動器用C++寫成,適合于所有Windows平臺。
  
  
  
  // Windows平臺下的Java程序啟動器
  
  // 適用于1.2或更高版本的VM
  
  #include
  
  #include
  
  #include
  
  using namespace std;
  
  void vShowError(string sErrorMessage);
  
  void vShowLastError(string sErrorMessage);
  
  void vDestroyVM(JNIEnv *env, JavaVM *jvm);
  
  void vAddOption(string& sName);
  
  JavaVMOption* vm_options;
  
  int mctOptions = 0;
  
  int mctOptionCapacity = 0;
  
  boolean GetapplicationHome(char *buf, jint sz);
  
  typedef jint (CALLBACK *CreateJavaVM)(JavaVM **pvm, JNIEnv **penv, void *args);
  
  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPRevInstance, PSTR szCmdLine, int iCmdShow){
  
  JNIEnv *env;
  
  JavaVM *jvm;
  
  jint jintVMStartupReturnValue;
  
  jclass jclassStartup;
  
  jmethodID midStartup;
  
  // 確定各種文件所在的路徑
  
  // -應用的主目錄
  
  char home[2000];
  
  if (!GetApplicationHome(home, sizeof(home))) {
  
  vShowError("不能確定應用的主目錄。");
  
  return 0;
  
  }
  
  string sAppHome(home);
  
  string sOption_AppHome = "-Dapplication.home=" + sAppHome;
  
  string sJREPath = sAppHome + "/jre";
  
  // -VM路徑
  
  string sRuntimePath = sJREPath + "/bin/classic/";
  
  string sJVMpath = sRuntimePath + "jvm.dll";
  
  // -啟動路徑
  
  string sBootPath = sJREPath + "/lib";
  
  string sOption_BootPath = "-Dsun.boot.class.path=" + sBootPath;
  
  // -CLASSPATH
  
  string sClassPath = sAppHome + "/classes";
  
  string sOption_ClassPath = "-Djava.class.path=" + sClassPath;
  
  // 設置VM參數
  
  // vAddOption(string("-verbose"));
  
  vAddOption(sOption_ClassPath);
  
  vAddOption(sOption_AppHome);
  
  // VM初始化參數
  
  JavaVMInitArgs vm_args;
  
  vm_args.version = 0x00010002;
  
  vm_args.options = vm_options;
  
  vm_args.nOptions = mctOptions;
  
  vm_args.ignoreUnrecognized = JNI_TRUE;
  
  // 裝入JVM庫
  
  HINSTANCE hJVM = LoadLibrary(sJVMpath.c_str());
  
  if( hJVM == NULL ){
  
  vShowLastError("不能從下面的路徑裝入JVM:" + sJVMpath);
  
  return 0;
  
  }
  
  // 啟動1.2/3/4 VM
  
  CreateJavaVM lpfnCreateJavaVM = (CreateJavaVM) GetProcAddress(hJVM, "JNI_CreateJavaVM");
  
  jintVMStartupReturnValue = (*lpfnCreateJavaVM) (&jvm, &env, &vm_args);
  
  // 是否成功?
  
  if (jintVMStartupReturnValue
  
  FindClass(sStartupClass.c_str());
  
  if (jclassStartup == NULL) {
  
  string sErrorMessage ="找不到啟動類[" +sStartupClass + "]";
  
  vShowError(sErrorMessage);
  
  vDestroyVM(env, jvm);
  
  return 0;
  
  }
  
  // 要啟動的方法
  
  string sStartupMethod_Identifier = "main";
  
  string sStartupMethod_TypeDescriptor ="([Ljava/lang/String;)V";
  
  midStartup = env->GetStaticMethodID(jclassStartup,
  
  sStartupMethod_Identifier.c_str(),
  
  sStartupMethod_TypeDescriptor.c_str());
  
  if (midStartup == NULL) {
  
  string sErrorMessage = "找不到啟動方法["+ sStartupClass + "."+ sStartupMethod_Identifier
  
  + "],類型描述符是[" + sStartupMethod_TypeDescriptor + "]";
  
  vShowError(sErrorMessage);
  
  vDestroyVM(env, jvm);
  
  return 0;
  
  }
  
  // 構造啟動方法的參數
  
  jstring jstringExampleArg;
  
  jclass jclassString;
  
  jobjectArray jobjectArray_args;
  
  jstringExampleArg = env->NewStringUTF("string1");
  
  if (jstringExampleArg == NULL){
  
  vDestroyVM(env, jvm);
  
  return 0;
  
  }
  
  jclassString = env->FindClass("java/lang/String");
  
  jobjectArray_args = env->NewObjectArray(1, jclassString, jstringExampleArg);
  
  if (jobjectArray_args == NULL){
  
  vDestroyVM(env, jvm);
  
  return 0;
  
  }
  
  // 調用啟動方法啟動Java程序
  
  env->CallStaticVoidMethod(jclassStartup, midStartup, jobjectArray_args);
  
  // 在退出之前嘗試分離主線程
  
  if (jvm->DetachCurrentThread() != 0) {
  
  vShowError("分離主線程失敗。/n");
  
  }
  
  // 只要還有非守護線程,下面的調用將一直被掛起
  
  jvm->DestroyJavaVM();
  
  return 0;
  
  }
  
  void vDestroyVM(JNIEnv *env, JavaVM *jvm){
  
  if (env->ExceptionOccurred()) {
  
  env->ExceptionDescribe();
  
  }
  
  jvm->DestroyJavaVM();
  
  }
  
  void vShowError(string sError) {
  
  MessageBox(NULL, sError.c_str(), "錯誤", MB_OK);
  
  }
  
  /* 在對話框中顯示錯誤信息,括號內包含
  
  的GetLastError錯誤信息 */
  
  void vShowLastError(string sLocalError) {
  
  LPVOID lpSystemMsgBuf;
  
  FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
  
  FORMAT_MESSAGE_FROM_SYSTEM FORMAT_MESSAGE_IGNORE_INSERTS,
  
  NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  
  (LPTSTR) &

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久久国产精品久久久久久 | 成人免费一区二区三区在线观看 | 欧美日韩亚洲在线 | 全免费午夜一级毛片真人 | 久久久久久久99 | 日本在线免费观看视频 | 欧美aaaaa一级毛片在线 | 欧美自拍三区 | 中文区永久区 | 成人毛片免费 | 九九精品免费 | 亚洲第一页综合 | 91在线色| 一区在线免费视频 | 亚洲午夜激情网 | 一本视频在线观看 | 在线成人免费av | 欧美日韩在线播放一区 | 国产午夜精品在线 | av在线播放电影 | 欧美在线黄色 | 国产成人av在线播放 | av在线收看| 一级做a爱片毛片免费 | 经典三级在线视频 | 亚洲网视频 | 毛片视频网站在线观看 | 成年人网站视频免费 | 精品久久久久久久久久久久久久 | 欧美日韩大片在线观看 | 成人国产精品一区 | 伊人午夜视频 | 亚洲自拍第一 | 免看黄大片aa | 免费国产视频在线观看 | 密室逃脱第一季免费观看完整在线 | 日本a大片| 精品久久久久久久久久久久久久 | 久久精品视频一区二区三区 | 精品亚洲va在线va天堂资源站 | h视频免费观看 |