国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

打造個(gè)性化Java啟動器

2019-11-18 13:27:03
字體:
供稿:網(wǎng)友

  主要內(nèi)容:
  
  ________________________
  
   一、java程序的啟動過程
  
   二、Windows平臺的啟動器
  
   三、配置和使用
  
  ________________________
  
  對于普通用戶來說,Java最讓人不習(xí)慣的是程序的啟動過程;即使對于富有經(jīng)驗(yàn)的開發(fā)者,為了用默認(rèn)的裝載器啟動Java程序,不得不編寫大量批命令、腳本文件,不得不在命令行環(huán)境下進(jìn)行大量的復(fù)制/粘貼操作,也很輕易出現(xiàn)誤操作。
  
  用慣了Windows方便快捷的GUI,人們早就習(xí)慣了通過雙擊運(yùn)行程序的方式。對于Java程序,要實(shí)現(xiàn)這個(gè)本機(jī)啟動功能就必須編寫定制的啟動器。用定制啟動器啟動Java程序不僅方便了最終用戶,而且使軟件作品看起來更專業(yè)。本文就以Windows平臺為例,介紹如何構(gòu)造Java定制啟動器。
  打造個(gè)性化Java啟動器
  Java程序可以由任何本機(jī)運(yùn)行的程序調(diào)用執(zhí)行。所謂Java啟動器,就是一個(gè)專門用來啟動Java程序的本機(jī)執(zhí)行程序。最常見的啟動器是Sun在Java Runtime Environment的/bin目錄中提供的啟動器,就Windows平臺而言,它們是java.exe和javaw.exe。前者運(yùn)行時(shí)打開兩個(gè)窗口:一個(gè)是接收System.out/err和啟動器輸出的控制臺窗口,另一個(gè)是Java程序本身的窗口;javaw運(yùn)行時(shí)不打開控制臺窗口。在J2SE/EE平臺中,虛擬機(jī)以動態(tài)庫的形式實(shí)現(xiàn),也放在/bin目錄下。動態(tài)庫的名字在Windows中是java.dll,在Unix中是java.so。所謂“裝入虛擬機(jī)”,就是指裝入這個(gè)動態(tài)庫。
  
  提供給VM的參數(shù)可以通過兩種方式指定,或者是在啟動器的命令行參數(shù)中指定,或者通過定義相應(yīng)的環(huán)境變量指定。只有一個(gè)參數(shù)例外——要啟動的類的名稱只能在啟動器的命令行參數(shù)中指定。雖然指定方式的多樣姓為人們各取所需帶來了方便,但不可否認(rèn)地,它也正是許多混亂的根源。使用定制啟動器能夠完全避免這方面的問題。
  
  當(dāng)VM結(jié)束啟動類的main()方法的運(yùn)行,啟動器調(diào)用destroy()方法釋放各種資源并退出。應(yīng)當(dāng)注重的是,VM一旦開始運(yùn)行,我們就不能再卸載它。對于Java啟動器來說,能否關(guān)閉VM無關(guān)緊要,因?yàn)閱悠鲿S著Java程序的退出而退出;然而,對于嵌入了VM的本機(jī)應(yīng)用,例如瀏覽器,這意味著有一塊內(nèi)存被永久姓地占用,不能再收回。
  
  二、Windows平臺的啟動器
  
  搞清楚了Java程序的啟動過程,我們就可以開始編寫啟動器的代碼。下面這個(gè)啟動器用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;
  
  // 確定各種文件所在的路徑
  
  // -應(yīng)用的主目錄
  
  char home[2000];
  
  if (!GetApplicationHome(home, sizeof(home))) {
  
  vShowError("不能確定應(yīng)用的主目錄。");
  
  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;
  
  // 設(shè)置VM參數(shù)
  
  // vAddOption(string("-verbose"));
  
  vAddOption(sOption_ClassPath);
  
  vAddOption(sOption_AppHome);
  
  // VM初始化參數(shù)
  
  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;
  
  }
  
  // 構(gòu)造啟動方法的參數(shù)
  
  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;
  
  }
  
  // 調(diào)用啟動方法啟動Java程序
  
  env->CallStaticVoidMethod(jclassStartup, midStartup, jobjectArray_args);
  
  // 在退出之前嘗試分離主線程
  
  if (jvm->DetachCurrentThread() != 0) {
  
  vShowError("分離主線程失敗。/n");
  
  }
  
  // 只要還有非守護(hù)線程,下面的調(diào)用將一直被掛起
  
  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(), "錯(cuò)誤", MB_OK);
  
  }
  
  /* 在對話框中顯示錯(cuò)誤信息,括號內(nèi)包含
  
  的GetLastError錯(cuò)誤信息 */
  
  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) &

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 凤台县| 洪湖市| 方正县| 承德市| 盘山县| 泸州市| 保康县| 息烽县| 延安市| 莒南县| 磴口县| 富平县| 白沙| 五大连池市| 白山市| 新田县| 曲水县| 大庆市| 密山市| 鄂托克旗| 诸暨市| 故城县| 高台县| 大英县| 宁津县| 永寿县| 南郑县| 威海市| 油尖旺区| 区。| 长泰县| 英吉沙县| 噶尔县| 茌平县| 阿勒泰市| 山西省| 新宾| 西畴县| 周宁县| 论坛| 新乐市|