From df96b9bdb4b01d9023a967b92f05ee3471922605 Mon Sep 17 00:00:00 2001 From: Neil C Smith Date: Tue, 19 Dec 2023 14:10:03 +0000 Subject: [PATCH 1/2] Copy Windows launcher sources back from https://github.com/apache/netbeans-native-launchers --- .../windows-launcher-src/Makefile.mingw | 41 + .../windows-launcher-src/app.cpp | 29 + .../windows-launcher-src/app.exe.manifest | 75 + .../windows-launcher-src/app.ico | Bin 0 -> 21174 bytes .../windows-launcher-src/app.rc | 26 + .../windows-launcher-src/applauncher.cpp | 141 ++ .../windows-launcher-src/applauncher.h | 67 + nb/ide.launcher/windows/Makefile.mingw | 40 + nb/ide.launcher/windows/cmdargs.h | 119 ++ nb/ide.launcher/windows/nblauncher.cpp | 554 +++++ nb/ide.launcher/windows/nblauncher.h | 107 + nb/ide.launcher/windows/netbeans.cpp | 29 + nb/ide.launcher/windows/netbeans.exe.manifest | 77 + nb/ide.launcher/windows/netbeans.ico | Bin 0 -> 99678 bytes nb/ide.launcher/windows/netbeans.rc | 31 + .../windows/netbeans64.exe.manifest | 77 + nb/ide.launcher/windows/version.h | 28 + nb/ide.launcher/windows/version.rc | 62 + .../launcher/windows/Makefile.mingw | 52 + .../o.n.bootstrap/launcher/windows/argnames.h | 41 + .../launcher/windows/include/README | 18 + .../launcher/windows/include/jni.h | 1838 +++++++++++++++++ .../launcher/windows/include/jni_types.h | 451 ++++ .../launcher/windows/jvmlauncher.cpp | 454 ++++ .../launcher/windows/jvmlauncher.h | 123 ++ .../o.n.bootstrap/launcher/windows/nbexec.cpp | 70 + .../launcher/windows/nbexec.exe.manifest | 75 + .../o.n.bootstrap/launcher/windows/nbexec.rc | 26 + .../launcher/windows/nbexec_exe.rc | 29 + .../launcher/windows/nbexecexe.cpp | 32 + .../launcher/windows/nbexecloader.h | 66 + .../launcher/windows/platformlauncher.cpp | 735 +++++++ .../launcher/windows/platformlauncher.h | 112 + .../launcher/windows/utilsfuncs.cpp | 464 +++++ .../launcher/windows/utilsfuncs.h | 52 + .../o.n.bootstrap/launcher/windows/version.h | 28 + .../o.n.bootstrap/launcher/windows/version.rc | 63 + 37 files changed, 6232 insertions(+) create mode 100644 harness/apisupport.harness/windows-launcher-src/Makefile.mingw create mode 100644 harness/apisupport.harness/windows-launcher-src/app.cpp create mode 100644 harness/apisupport.harness/windows-launcher-src/app.exe.manifest create mode 100644 harness/apisupport.harness/windows-launcher-src/app.ico create mode 100644 harness/apisupport.harness/windows-launcher-src/app.rc create mode 100644 harness/apisupport.harness/windows-launcher-src/applauncher.cpp create mode 100644 harness/apisupport.harness/windows-launcher-src/applauncher.h create mode 100644 nb/ide.launcher/windows/Makefile.mingw create mode 100644 nb/ide.launcher/windows/cmdargs.h create mode 100644 nb/ide.launcher/windows/nblauncher.cpp create mode 100644 nb/ide.launcher/windows/nblauncher.h create mode 100644 nb/ide.launcher/windows/netbeans.cpp create mode 100644 nb/ide.launcher/windows/netbeans.exe.manifest create mode 100644 nb/ide.launcher/windows/netbeans.ico create mode 100644 nb/ide.launcher/windows/netbeans.rc create mode 100644 nb/ide.launcher/windows/netbeans64.exe.manifest create mode 100644 nb/ide.launcher/windows/version.h create mode 100644 nb/ide.launcher/windows/version.rc create mode 100644 platform/o.n.bootstrap/launcher/windows/Makefile.mingw create mode 100644 platform/o.n.bootstrap/launcher/windows/argnames.h create mode 100644 platform/o.n.bootstrap/launcher/windows/include/README create mode 100644 platform/o.n.bootstrap/launcher/windows/include/jni.h create mode 100644 platform/o.n.bootstrap/launcher/windows/include/jni_types.h create mode 100644 platform/o.n.bootstrap/launcher/windows/jvmlauncher.cpp create mode 100644 platform/o.n.bootstrap/launcher/windows/jvmlauncher.h create mode 100644 platform/o.n.bootstrap/launcher/windows/nbexec.cpp create mode 100644 platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest create mode 100644 platform/o.n.bootstrap/launcher/windows/nbexec.rc create mode 100644 platform/o.n.bootstrap/launcher/windows/nbexec_exe.rc create mode 100644 platform/o.n.bootstrap/launcher/windows/nbexecexe.cpp create mode 100644 platform/o.n.bootstrap/launcher/windows/nbexecloader.h create mode 100644 platform/o.n.bootstrap/launcher/windows/platformlauncher.cpp create mode 100644 platform/o.n.bootstrap/launcher/windows/platformlauncher.h create mode 100644 platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp create mode 100644 platform/o.n.bootstrap/launcher/windows/utilsfuncs.h create mode 100644 platform/o.n.bootstrap/launcher/windows/version.h create mode 100644 platform/o.n.bootstrap/launcher/windows/version.rc diff --git a/harness/apisupport.harness/windows-launcher-src/Makefile.mingw b/harness/apisupport.harness/windows-launcher-src/Makefile.mingw new file mode 100644 index 000000000000..866b30dd1e54 --- /dev/null +++ b/harness/apisupport.harness/windows-launcher-src/Makefile.mingw @@ -0,0 +1,41 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +TMPFLD = ../../../../target/tmp/ +OFLD = ../../../../target/harness/ + +all: prepfolder app64.exe app.exe + +prepfolder: + mkdir -p $(TMPFLD) + mkdir -p $(OFLD) + +clean: + rm -f *.res *.exe + +app64.res: app.rc app.exe.manifest + x86_64-w64-mingw32-windres -o$(TMPFLD)app64.res -Ocoff -DMANIFEST_FILE=app.exe.manifest app.rc + +app64.exe: app.cpp applauncher.cpp app64.res ../bootstrap/utilsfuncs.cpp + x86_64-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec64.dll"' -DARCHITECTURE=64 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh app.cpp -mwindows applauncher.cpp $(TMPFLD)app64.res ../bootstrap/utilsfuncs.cpp ../ide/nblauncher.cpp -I ../bootstrap/ -o$(OFLD)app64.exe -static -lstdc++ -static-libstdc++ -static-libgcc + +app.res: app.rc app.exe.manifest + i686-w64-mingw32-windres -o$(TMPFLD)app.res -Ocoff -DMANIFEST_FILE=app.exe.manifest app.rc + +app.exe: app.cpp applauncher.cpp app.res ../bootstrap/utilsfuncs.cpp + i686-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec.dll"' -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows app.cpp applauncher.cpp $(TMPFLD)app.res ../bootstrap/utilsfuncs.cpp ../ide/nblauncher.cpp -I ../bootstrap/ -o$(OFLD)app.exe -static -lstdc++ -static-libstdc++ -static-libgcc + diff --git a/harness/apisupport.harness/windows-launcher-src/app.cpp b/harness/apisupport.harness/windows-launcher-src/app.cpp new file mode 100644 index 000000000000..840c8285e06e --- /dev/null +++ b/harness/apisupport.harness/windows-launcher-src/app.cpp @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + + +#include "applauncher.h" + +int main(int argc, char *argv[]) { + AppLauncher launcher; + return launcher.start(argc - 1, argv + 1); +} diff --git a/harness/apisupport.harness/windows-launcher-src/app.exe.manifest b/harness/apisupport.harness/windows-launcher-src/app.exe.manifest new file mode 100644 index 000000000000..c1843b229a94 --- /dev/null +++ b/harness/apisupport.harness/windows-launcher-src/app.exe.manifest @@ -0,0 +1,75 @@ + + + + + +NBP application process + + + + + + + + + + + + + + + + + UTF-8 + + + + + + true/PM + PerMonitorV2, PerMonitor, system + + + + + + + + + + + + + diff --git a/harness/apisupport.harness/windows-launcher-src/app.ico b/harness/apisupport.harness/windows-launcher-src/app.ico new file mode 100644 index 0000000000000000000000000000000000000000..294cd704d1988a7f5c1916944eb1e1921be13ccb GIT binary patch literal 21174 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 G=zjoy_nAfj literal 0 HcmV?d00001 diff --git a/harness/apisupport.harness/windows-launcher-src/app.rc b/harness/apisupport.harness/windows-launcher-src/app.rc new file mode 100644 index 000000000000..d52211e464c6 --- /dev/null +++ b/harness/apisupport.harness/windows-launcher-src/app.rc @@ -0,0 +1,26 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. + +#include + +100 ICON "app.ico" + +// Value MANIFEST_FILE id taken from windres parameter -DMANIFEST_FILE +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST MANIFEST_FILE diff --git a/harness/apisupport.harness/windows-launcher-src/applauncher.cpp b/harness/apisupport.harness/windows-launcher-src/applauncher.cpp new file mode 100644 index 000000000000..1fa9d4ee8165 --- /dev/null +++ b/harness/apisupport.harness/windows-launcher-src/applauncher.cpp @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#include "applauncher.h" +#include "../bootstrap/utilsfuncs.h" +#include "../bootstrap/argnames.h" + +using namespace std; + +const char *AppLauncher::OPT_DEFAULT_USER_DIR = "default_userdir="; +const char *AppLauncher::OPT_DEFAULT_CACHE_DIR = "default_cachedir="; +const char *AppLauncher::OPT_DEFAULT_OPTIONS = "default_options="; +const char *AppLauncher::OPT_EXTRA_CLUSTERS = "extra_clusters="; +const char *AppLauncher::OPT_JDK_HOME = "jdkhome="; +const char *AppLauncher::APPNAME_TOKEN = "${APPNAME}"; +const char *AppLauncher::CACHE_SUFFIX = "\\Cache\\"; + +AppLauncher::AppLauncher() { +} + +AppLauncher::AppLauncher(const AppLauncher& orig) { +} + +AppLauncher::~AppLauncher() { +} + +bool AppLauncher::initBaseNames() { + if (!NbLauncher::initBaseNames()) { + return false; + } + + string pattern = baseDir + "\\platform*"; + WIN32_FIND_DATA fd = {0}; + HANDLE hFind; + hFind = FindFirstFile(pattern.c_str(), &fd); + if (hFind == INVALID_HANDLE_VALUE) { + logErr(false, true, "Cannot find 'platform*' folder!"); + return false; + } + + do { + if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + && fileExists((baseDir + '\\' + fd.cFileName + NbLauncher::NBEXEC_FILE_PATH).c_str())) { + platformDir = baseDir + '\\' + fd.cFileName; + break; + } + } while (FindNextFile(hFind, &fd)); + + FindClose(hFind); + + if (platformDir.empty()) { + logErr(false, true, "Cannot find valid 'platform*' folder!"); + return false; + } + return true; +} + +bool AppLauncher::findUserDir(const char *str) { + logMsg("AppLauncher::findUserDir()"); + if (!NbLauncher::findUserDir(str)) { // will set userDir and possibly userHome. + return false; + } + int pos = userDir.find(APPNAME_TOKEN); + if (pos != string::npos) { + userDir.replace(pos, strlen(APPNAME_TOKEN), appName); + } + return true; +} + +bool AppLauncher::findCacheDir(const char *str) { + logMsg("AppLauncher::findCacheDir"); + if (!NbLauncher::findCacheDir(str)) { // will set userDir and possibly userHome. + return false; + } + int pos = cacheDir.find(APPNAME_TOKEN); + if (pos != string::npos) { + cacheDir.replace(pos, strlen(APPNAME_TOKEN), appName); + } + return true; +} + +const char * AppLauncher::getAppName() { + return appName.c_str(); +} + +void AppLauncher::addSpecificOptions(CmdArgs &args) { +} + +void AppLauncher::adjustHeapSize() { +} + +const char * AppLauncher::getDefUserDirOptName() { + return OPT_DEFAULT_USER_DIR; +} + +const char * AppLauncher::getDefCacheDirOptName() { + return OPT_DEFAULT_CACHE_DIR; +} + +const char * AppLauncher::getDefOptionsOptName() { + return OPT_DEFAULT_OPTIONS; +} + +const char * AppLauncher::getExtraClustersOptName() { + return OPT_EXTRA_CLUSTERS; +} + +const char * AppLauncher::getJdkHomeOptName() { + return OPT_JDK_HOME; +} + +const char * AppLauncher::getCurrentDir() { + return baseDir.c_str(); +} + +std::string AppLauncher::constructApplicationDir(const std::string& dir, bool cache) { + if (cache) { + return dir + "\\" + getAppName() + CACHE_SUFFIX; + } else { + return dir + "\\" + getAppName() + "\\"; + } +} diff --git a/harness/apisupport.harness/windows-launcher-src/applauncher.h b/harness/apisupport.harness/windows-launcher-src/applauncher.h new file mode 100644 index 000000000000..b6002fd95b7b --- /dev/null +++ b/harness/apisupport.harness/windows-launcher-src/applauncher.h @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#ifndef _APPLAUNCHER_H +#define _APPLAUNCHER_H + +#include +#include + +#include "shlobj.h" +#include "../ide/nblauncher.h" + +class AppLauncher : public NbLauncher { + + static const char *OPT_DEFAULT_USER_DIR; + static const char *OPT_DEFAULT_CACHE_DIR; + static const char *OPT_DEFAULT_OPTIONS; + static const char *OPT_EXTRA_CLUSTERS; + static const char *OPT_JDK_HOME; + static const char *APPNAME_TOKEN; + static const char *REG_APPDATA_NAME; + static const char *CACHE_SUFFIX; + +public: + AppLauncher(); + virtual ~AppLauncher(); + +protected: + virtual bool initBaseNames(); + virtual const char * getAppName(); + virtual void addSpecificOptions(CmdArgs &args); + virtual void adjustHeapSize(); + virtual bool findUserDir(const char *str); + virtual bool findCacheDir(const char *str); + virtual const char * getDefUserDirOptName(); + virtual const char * getDefCacheDirOptName(); + virtual const char * getDefOptionsOptName(); + virtual const char * getExtraClustersOptName(); + virtual const char * getJdkHomeOptName(); + virtual const char * getCurrentDir(); + virtual std::string constructApplicationDir(const std::string& dir, bool cache); + +private: + AppLauncher(const AppLauncher& orig); +}; + +#endif /* _NBLAUNCHER_H */ + diff --git a/nb/ide.launcher/windows/Makefile.mingw b/nb/ide.launcher/windows/Makefile.mingw new file mode 100644 index 000000000000..6db2f87fc281 --- /dev/null +++ b/nb/ide.launcher/windows/Makefile.mingw @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +TMPFLD = ../../../../target/tmp/ +OFLD = ../../../../target/ide/ + +all: prepfolder netbeans64.exe netbeans.exe + +prepfolder: + mkdir -p $(TMPFLD) + mkdir -p $(OFLD) + +clean: + rm -f *.res *.exe + +netbeans64.res: netbeans.rc netbeans64.exe.manifest + x86_64-w64-mingw32-windres -o$(TMPFLD)netbeans64.res -Ocoff -DMANIFEST_FILE=netbeans64.exe.manifest netbeans.rc + +netbeans64.exe: netbeans.cpp nblauncher.cpp netbeans64.res ../bootstrap/utilsfuncs.cpp + x86_64-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec64.dll"' -DARCHITECTURE=64 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows netbeans.cpp nblauncher.cpp $(TMPFLD)netbeans64.res ../bootstrap/utilsfuncs.cpp -I ../bootstrap/ -o$(OFLD)netbeans64.exe -static -lstdc++ -static-libstdc++ -static-libgcc + +netbeans.res: netbeans.rc netbeans.exe.manifest + i686-w64-mingw32-windres -o$(TMPFLD)netbeans.res -Ocoff -DMANIFEST_FILE=netbeans.exe.manifest netbeans.rc + +netbeans.exe: netbeans.cpp nblauncher.cpp netbeans.res ../bootstrap/utilsfuncs.cpp + i686-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec.dll"' -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows netbeans.cpp nblauncher.cpp $(TMPFLD)netbeans.res ../bootstrap/utilsfuncs.cpp -I ../bootstrap/ -o$(OFLD)netbeans.exe -static -lstdc++ -static-libstdc++ -static-libgcc diff --git a/nb/ide.launcher/windows/cmdargs.h b/nb/ide.launcher/windows/cmdargs.h new file mode 100644 index 000000000000..acf56a411e79 --- /dev/null +++ b/nb/ide.launcher/windows/cmdargs.h @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#ifndef _CMDARGS_H +#define _CMDARGS_H + +class CmdArgs { +public: + + CmdArgs(int _count) { + used = 0; + size = _count; + args = new char*[size]; + memset(args, 0, size * sizeof (char*)); + } + + ~CmdArgs() { + if (args) { + for (int i = 0; i < size; i++) { + delete[] args[i]; + } + delete[] args; + } + } + + void add(const char *arg) { + if (used + 1 > size) { + int newSize = size + size / 2 + 1; + char **newArgs = new char*[newSize]; + memcpy(newArgs, args, size * sizeof (char*)); + memset(newArgs + size, 0, (newSize - size) * sizeof (char*)); + delete[] args; + args = newArgs; + size = newSize; + } + args[used] = new char[strlen(arg) + 1]; + strcpy(args[used++], arg); + } + + void addCmdLine(const char *cmdLine) { + char arg[1024] = ""; + bool inQuotes = false; + bool inText = false; + int i = 0; + int j = 0; + char c; + while (c = cmdLine[i]) { + if (inQuotes) { + if (c == '\"') { + inQuotes = false; + } else { + arg[j++] = c; + } + } else { + switch (c) { + case '\"': + inQuotes = true; + inText = true; + break; + case ' ': + case '\t': + case '\n': + case '\r': + if (inText) { + arg[j] = '\0'; + add(arg); + j = 0; + } + inText = false; + break; + default: + inText = true; + arg[j++] = c; + break; + } + } + i++; + } + if (j > 0) { + arg[j] = '\0'; + add(arg); + } + } + + int getCount() { + return used; + } + + char **getArgs() { + return args; + } + +private: + int used; + int size; + char **args; +}; + +#endif /* _CMDARGS_H */ + diff --git a/nb/ide.launcher/windows/nblauncher.cpp b/nb/ide.launcher/windows/nblauncher.cpp new file mode 100644 index 000000000000..393e2cd81a27 --- /dev/null +++ b/nb/ide.launcher/windows/nblauncher.cpp @@ -0,0 +1,554 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x05010100 +#endif + +#include +#include +#include "nblauncher.h" +#include "../bootstrap/utilsfuncs.h" +#include "../bootstrap/argnames.h" +#include "../bootstrap/nbexecloader.h" + +using namespace std; + +const char *NbLauncher::NBEXEC_FILE_PATH = NBEXEC_DLL; +const char *NbLauncher::OPT_NB_DEFAULT_USER_DIR = "netbeans_default_userdir="; +const char *NbLauncher::OPT_NB_DEFAULT_CACHE_DIR = "netbeans_default_cachedir="; +const char *NbLauncher::OPT_NB_DEFAULT_OPTIONS = "netbeans_default_options="; +const char *NbLauncher::OPT_NB_EXTRA_CLUSTERS = "netbeans_extraclusters="; +const char *NbLauncher::OPT_NB_JDK_HOME = "netbeans_jdkhome="; +const char *NbLauncher::ENV_USER_PROFILE = "USERPROFILE"; +const char *NbLauncher::HOME_TOKEN = "${HOME}"; +const char *NbLauncher::DEFAULT_USERDIR_ROOT_TOKEN = "${DEFAULT_USERDIR_ROOT}"; +const char *NbLauncher::DEFAULT_CACHEDIR_ROOT_TOKEN = "${DEFAULT_CACHEDIR_ROOT}"; +const char *NbLauncher::NETBEANS_DIRECTORY = "\\NetBeans\\"; +const char *NbLauncher::NETBEANS_CACHES_DIRECTORY = "\\NetBeans\\Cache\\"; + +const char *NbLauncher::CON_ATTACH_MSG = +"\n\nThe launcher has determined that the parent process has a console and will reuse it for its own console output.\n" +"Closing the console will result in termination of the running program.\n" +"Use '--console suppress' to suppress console output.\n" +"Use '--console new' to create a separate console window.\n"; + +const char *NbLauncher::staticOptions[] = { + "-J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade", + "--branding", + "nb" +}; + +NbLauncher::NbLauncher() { +} + +NbLauncher::NbLauncher(const NbLauncher& orig) { +} + +NbLauncher::~NbLauncher() { +} + +int NbLauncher::start(char *cmdLine) { + CmdArgs args(50); + args.addCmdLine(cmdLine); + return start(args.getCount(), args.getArgs()); +} + +int NbLauncher::start(int argc, char *argv[]) { + SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); + + DWORD parentProcID = 0; + if (!checkLoggingArg(argc, argv, true) || !setupProcess(argc, argv, parentProcID, CON_ATTACH_MSG) || !initBaseNames() || !readClusterFile()) { + return -1; + } + + parseConfigFile((baseDir + "\\etc\\" + getAppName() + ".conf").c_str()); + + if (!parseArgs(argc, argv)) { + return -1; + } + string oldUserDir = userDir; + parseConfigFile((userDir + "\\etc\\" + getAppName() + ".conf").c_str()); + userDir = oldUserDir; + + addExtraClusters(); + string nbexecPath; + SetDllDirectory(baseDir.c_str()); + if (dirExists(platformDir.c_str())) { + nbexecPath = platformDir; + } else { + nbexecPath = baseDir + '\\' + platformDir; + } + if (!dirExists(nbexecPath.c_str())) { + logErr(false, true, "Could not find platform cluster:\n%s", nbexecPath.c_str()); + return false; + } + + CmdArgs newArgs(argc + 20); + addSpecificOptions(newArgs); + + if (!clusters.empty()) { + newArgs.add(ARG_NAME_CLUSTERS); + newArgs.add(clusters.c_str()); + } + if (!userDir.empty()) { + newArgs.add(ARG_NAME_USER_DIR); + newArgs.add(userDir.c_str()); + } + if (!defUserDirRoot.empty()) { + newArgs.add(ARG_DEFAULT_USER_DIR_ROOT); + newArgs.add(defUserDirRoot.c_str()); + } + if (!cacheDir.empty() && !customUserDirFound) { + newArgs.add(ARG_NAME_CACHE_DIR); + newArgs.add(cacheDir.c_str()); + } + if (!nbOptions.empty()) { + newArgs.addCmdLine(nbOptions.c_str()); + } + for (int i = 0; i < argc; i++) { + newArgs.add(argv[i]); + } + if (!jdkHome.empty()) { + newArgs.add(ARG_NAME_JDKHOME); + newArgs.add(jdkHome.c_str()); + } + if (parentProcID) { + newArgs.add(ARG_NAME_LA_PPID); + char tmp[16] = ""; + newArgs.add(itoa(parentProcID, tmp, 10)); + } + nbexecPath += NBEXEC_FILE_PATH; + + const char *curDir = getCurrentDir(); + if (curDir) { + char olddir[MAX_PATH]; + DWORD rc = GetCurrentDirectory(MAX_PATH, olddir); + if (rc == 0) { + logErr(true, false, "Failed to get current directory"); + } else { + string od = string(olddir); + od.insert(0, "-J-Dnetbeans.user.dir="); + newArgs.add(od.c_str()); + } + logMsg("Changing current directory to: \"%s\"", curDir); + SetCurrentDirectory(curDir); + } + + NBExecLoader loader; + return loader.start(nbexecPath.c_str(), newArgs.getCount(), newArgs.getArgs()); +} + +UINT GetAnsiCodePageForLocale(LCID lcid) { + // See https://devblogs.microsoft.com/oldnewthing/20161007-00/?p=94475 + UINT acp; + int sizeInChars = sizeof(acp) / sizeof(TCHAR); + if (GetLocaleInfo(lcid, + LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, + reinterpret_cast(&acp), + sizeInChars) != sizeInChars) + { + return 0; + } + return acp; +} + +bool NbLauncher::initBaseNames() { + char path[MAX_PATH] = ""; + getCurrentModulePath(path, MAX_PATH); + logMsg("Executable: %s", path); + char *bslash = strrchr(path, '\\'); + if (!bslash) { + return false; + } + appName = bslash + 1; + appName.erase(appName.rfind('.')); + + if (ARCHITECTURE == 64) { + appName = appName.erase(appName.length() - 2); + } + + logMsg("Application name: %s", appName.c_str()); + + *bslash = '\0'; + bslash = strrchr(path, '\\'); + if (!bslash) { + return false; + } + *bslash = '\0'; + + /* Useful messages for debugging character set issues. On Java versions where + https://bugs.openjdk.org/browse/JDK-8272352 has been fixed, NetBeans should now run fine when + there are Unicode characters in the NetBeans installation path, the JDK path, the user/cache + directory paths, or in the java.io.tmpdir path (the latter sometimes being a problem for JNA, + which is used by FlatLAF). Since the JVM is started in-process via JNI, the Java environment + will inherit the UTF-8 code page setting that we have set in the launcher's application + manifest, without requiring the user to change regional settings in the Control Panel. (JEP 400 + might eventually do something similar for the java.exe/javaw.exe executables. See + https://www.mail-archive.com/core-libs-dev@openjdk.java.net/msg80489.html .) */ + logMsg("ANSI code page per GetACP() : %d", GetACP()); + logMsg("ANSI code page per GetConsoleCP() : %d", GetConsoleCP()); + logMsg("ANSI code page for GetThreadLocale() : %d", GetAnsiCodePageForLocale(GetThreadLocale())); + logMsg("ANSI code page for GetUserDefaultLCID() : %d", GetAnsiCodePageForLocale(GetUserDefaultLCID())); + logMsg("ANSI code page for GetSystemDefaultLCID(): %d", GetAnsiCodePageForLocale(GetSystemDefaultLCID())); + + baseDir = path; + + logMsg("Base dir: %s", baseDir.c_str()); + return true; +} + +void NbLauncher::addCluster(const char *cluster) { + + class SetCurDir { + public: + SetCurDir(const char *dir) { + oldCurDir[0] = '\0'; + DWORD rc = GetCurrentDirectory(MAX_PATH, oldCurDir); + if (rc == 0) { + logErr(true, false, "Failed to get current directory"); + return; + } + if (rc > MAX_PATH) { + logMsg("Failed to get current directory, buffer is too small."); + return; + } + if (!SetCurrentDirectory(dir)) { + logErr(true, true, "Failed to set current directory to \"%s\"", dir); + oldCurDir[0] = '\0'; + } + } + + ~SetCurDir() { + if (oldCurDir[0]) { + if (!SetCurrentDirectory(oldCurDir)) { + logErr(true, true, "Failed to set current directory to \"%s\"", oldCurDir); + } + } + } + private: + char oldCurDir[MAX_PATH]; + }; + + logMsg("addCluster: %s", cluster); + SetCurDir setCurDir(baseDir.c_str()); + char clusterPath[MAX_PATH + 1] = {0}; + strncpy(clusterPath, cluster, MAX_PATH); + if (!normalizePath(clusterPath, MAX_PATH)) { + logMsg("Invalid cluster path: %s", cluster); + return; + } + if (!clusters.empty()) { + clusters += ';'; + } + logMsg("Adding cluster %s", clusterPath); + clusters += clusterPath; +} + +void NbLauncher::addExtraClusters() { + logMsg("addExtraClusters()"); + const char delim = ';'; + string::size_type start = extraClusters.find_first_not_of(delim, 0); + string::size_type end = extraClusters.find_first_of(delim, start); + while (string::npos != end || string::npos != start) { + string cluster = extraClusters.substr(start, end - start); + addCluster(cluster.c_str()); + start = extraClusters.find_first_not_of(delim, end); + end = extraClusters.find_first_of(delim, start); + } +} + +bool NbLauncher::readClusterFile() { + clusters = ""; + string clusterFile = baseDir + "\\etc\\" + getAppName() + ".clusters"; + logMsg("readClusterFile() file: %s", clusterFile.c_str()); + + FILE* file = fopen(clusterFile.c_str(), "r"); + if (!file) { + logErr(true, true, "Cannot open file \"%s\" for reading.", clusterFile.c_str()); + return false; + } + + char line[4096] = ""; + while (fgets(line, sizeof(line), file)) { + char *str = skipWhitespaces(line); + if (*str == '#' || *str == '\0') { + continue; + } + char *pc = str; + while (*pc != '\0' && *pc != '\t' && *pc != '\n' && *pc != '\r') { + pc++; + } + *pc = '\0'; + + if (platformDir.empty()) { + char *slash = strrchr(str, '\\'); + if (!slash) { + slash = strrchr(str, '/'); + } + char *dir = slash ? slash + 1 : str; + if (strncmp(dir, "platform", strlen("platform")) == 0) { + platformDir = str; + } else { + addCluster(str); + } + } else { + addCluster(str); + } + } + bool ok = ferror(file) == 0; + if (!ok) { + logErr(true, true, "Error while reading file \"%s\".", clusterFile.c_str()); + } + fclose(file); + return ok; +} + +bool NbLauncher::parseArgs(int argc, char *argv[]) { +#define CHECK_ARG \ + if (i+1 == argc) {\ + logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]);\ + return false;\ + } + + logMsg("parseArgs():"); + for (int i = 0; i < argc; i++) { + logMsg("\t%s", argv[i]); + } + customUserDirFound = 0; + for (int i = 0; i < argc; i++) { + if (strcmp(ARG_NAME_USER_DIR, argv[i]) == 0) { + CHECK_ARG; + char tmp[MAX_PATH + 1] = {0}; + strncpy(tmp, argv[++i], MAX_PATH); + if (!normalizePath(tmp, MAX_PATH)) { + logErr(false, true, "User directory path \"%s\" is not valid.", argv[i]); + return false; + } + customUserDirFound = 1; + userDir = tmp; + logMsg("User dir: %s", userDir.c_str()); + } + if (strcmp(ARG_NAME_CACHE_DIR, argv[i]) == 0) { + CHECK_ARG; + char tmp[MAX_PATH + 1] = {0}; + strncpy(tmp, argv[++i], MAX_PATH); + if (!normalizePath(tmp, MAX_PATH)) { + logErr(false, true, "Cache directory path \"%s\" is not valid.", argv[i]); + return false; + } + cacheDir = tmp; + logMsg("Cache dir: %s", cacheDir.c_str()); + } + } + logMsg("parseArgs() finished"); + return true; +} + +bool NbLauncher::findUserDir(const char *str) { + logMsg("NbLauncher::findUserDir()"); + if (strncmp(str, HOME_TOKEN, strlen(HOME_TOKEN)) == 0) { + if (userHome.empty()) { + char *userProfile = getenv(ENV_USER_PROFILE); + if (userProfile) { + userHome = userProfile; + } else { + TCHAR userHomeChar[MAX_PATH]; + if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, userHomeChar))) { + return false; + } + userHome = userHomeChar; + userHome.erase(userHome.rfind('\\')); + } + logMsg("User home: %s", userHome.c_str()); + } + userDir = userHome + (str + strlen(HOME_TOKEN)); + } else if (strncmp(str, DEFAULT_USERDIR_ROOT_TOKEN, strlen(DEFAULT_USERDIR_ROOT_TOKEN)) == 0) { + std::string s = std::string("Replacing ") + DEFAULT_USERDIR_ROOT_TOKEN; + logMsg(s.c_str()); + userDir = getDefaultUserDirRoot() + (str + strlen(DEFAULT_USERDIR_ROOT_TOKEN)); + } else { + getDefaultUserDirRoot(); + userDir = str; + } + return true; +} + +bool NbLauncher::findCacheDir(const char *str) { + logMsg("NbLauncher::findCacheDir()"); + if (strncmp(str, HOME_TOKEN, strlen(HOME_TOKEN)) == 0) { + if (userHome.empty()) { + char *userProfile = getenv(ENV_USER_PROFILE); + if (userProfile) { + userHome = userProfile; + } else { + TCHAR userHomeChar[MAX_PATH]; + if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, userHomeChar))) { + return false; + } + userHome = userHomeChar; + userHome.erase(userHome.rfind('\\')); + } + logMsg("User home: %s", userHome.c_str()); + } + cacheDir = userHome + (str + strlen(HOME_TOKEN)); + } else if (strncmp(str, DEFAULT_CACHEDIR_ROOT_TOKEN, strlen(DEFAULT_CACHEDIR_ROOT_TOKEN)) == 0) { + std::string s = std::string("Replacing ") + DEFAULT_CACHEDIR_ROOT_TOKEN; + logMsg(s.c_str()); + cacheDir = getDefaultCacheDirRoot() + (str + strlen(DEFAULT_CACHEDIR_ROOT_TOKEN)); + } else { + getDefaultCacheDirRoot(); + cacheDir = str; + } + return true; +} + +string NbLauncher::getDefaultUserDirRoot() { + TCHAR defUserDirRootChar[MAX_PATH]; + if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, defUserDirRootChar))) { + return std::string(); + } + defUserDirRoot = constructApplicationDir((string) defUserDirRootChar, false); + defUserDirRoot.erase(defUserDirRoot.rfind('\\')); + logMsg("Default Userdir Root: %s", defUserDirRoot.c_str()); + return defUserDirRoot; +} + +string NbLauncher::getDefaultCacheDirRoot() { + TCHAR defCacheDirRootChar[MAX_PATH]; + if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, defCacheDirRootChar))) { + return std::string(); + } + defCacheDirRoot = constructApplicationDir((string) defCacheDirRootChar, true); + defCacheDirRoot.erase(defCacheDirRoot.rfind('\\')); + logMsg("Default Cachedir Root: %s", defCacheDirRoot.c_str()); + return defCacheDirRoot; +} + +bool NbLauncher::getOption(char *&str, const char *opt) { + if (strncmp(str, opt, strlen(opt)) == 0) { + str += strlen(opt); + char *end = trimWhitespaces(str); + if (*str == '"') { + str++; + } + if (end >= str && *end == '"') { + *end = '\0'; + } + logMsg("Option found: %s%s", opt, str); + return true; + } + return false; +} + +bool NbLauncher::parseConfigFile(const char* path) { + logMsg("parseConfigFile(%s)", path); + FILE *file = fopen(path, "r"); + if (!file) { + logErr(true, false, "Cannot open file \"%s\" for reading.", path); + return false; + } + + char line[4096] = ""; + while (fgets(line, sizeof(line), file)) { + char *str = skipWhitespaces(line); + if (*str == '#') { + continue; + } + if (getOption(str, getDefUserDirOptName())) { + findUserDir(str); + logMsg("User dir: %s", userDir.c_str()); + } else if (getOption(str, getDefCacheDirOptName())) { + findCacheDir(str); + logMsg("Cache dir: %s", cacheDir.c_str()); + } else if (getOption(str, getDefOptionsOptName())) { + // replace \" by " + int len = strlen(str); + int k = 0; + for (int i = 0; i < len; i++) { + if (str[i] == '\\' && str[i+1] == '\"') { + continue; + } + str[k++] = str[i]; + } + str[k] = '\0'; + nbOptions = str; + logMsg("After replacement: %s", nbOptions.c_str()); + + } else if (getOption(str, getExtraClustersOptName())) { + extraClusters = str; + } else if (getOption(str, getJdkHomeOptName())) { + jdkHome = str; + } + } + bool ok = ferror(file) == 0; + if (!ok) { + logErr(true, false, "Error while reading file \"%s\".", path); + } + fclose(file); + return true; +} + +typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); + +const char * NbLauncher::getAppName() { + return "netbeans"; +} + +void NbLauncher::addSpecificOptions(CmdArgs &args) { + for (unsigned i = 0; i < sizeof (staticOptions) / sizeof (char*); i++) { + args.add(staticOptions[i]); + } +} + +const char * NbLauncher::getDefUserDirOptName() { + return OPT_NB_DEFAULT_USER_DIR; +} + +const char * NbLauncher::getDefCacheDirOptName() { + return OPT_NB_DEFAULT_CACHE_DIR; +} + + +const char * NbLauncher::getDefOptionsOptName() { + return OPT_NB_DEFAULT_OPTIONS; +} + +const char * NbLauncher::getExtraClustersOptName() { + return OPT_NB_EXTRA_CLUSTERS; +} + +const char * NbLauncher::getJdkHomeOptName() { + return OPT_NB_JDK_HOME; +} + +const char * NbLauncher::getCurrentDir() { + return 0; +} + +std::string NbLauncher::constructApplicationDir(const std::string& dir, bool cache) { + if (cache) { + return dir + NETBEANS_CACHES_DIRECTORY; + } else { + return dir + NETBEANS_DIRECTORY; + } +} diff --git a/nb/ide.launcher/windows/nblauncher.h b/nb/ide.launcher/windows/nblauncher.h new file mode 100644 index 000000000000..469a21f4fa89 --- /dev/null +++ b/nb/ide.launcher/windows/nblauncher.h @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#ifndef _NBLAUNCHER_H +#define _NBLAUNCHER_H + +#include +#include +#include +#include "cmdargs.h" + +class NbLauncher { +protected: + static const char *NBEXEC_FILE_PATH; + static const char *OPT_NB_DEFAULT_USER_DIR; + static const char *OPT_NB_DEFAULT_CACHE_DIR; + static const char *OPT_NB_DEFAULT_OPTIONS; + static const char *OPT_NB_EXTRA_CLUSTERS; + static const char *OPT_NB_JDK_HOME; + static const char *REG_SHELL_FOLDERS_KEY; + static const char *HOME_TOKEN; + static const char *DEFAULT_USERDIR_ROOT_TOKEN; + static const char *DEFAULT_CACHEDIR_ROOT_TOKEN; + static const char *CON_ATTACH_MSG; + static const char *NETBEANS_DIRECTORY; + static const char *NETBEANS_CACHES_DIRECTORY; + +private: + static const char *ENV_USER_PROFILE; + static const char *REG_DESKTOP_NAME; + static const char *REG_DEFAULT_USERDIR_ROOT; + static const char *REG_DEFAULT_CACHEDIR_ROOT; + static const char* staticOptions[]; + + typedef int (*StartPlatform)(int argc, char *argv[]); + +public: + NbLauncher(); + virtual ~NbLauncher(); + + int start(int argc, char *argv[]); + int start(char *cmdLine); + +protected: + virtual bool initBaseNames(); + virtual void addSpecificOptions(CmdArgs &args); + virtual bool findUserDir(const char *str); + virtual bool findCacheDir(const char *str); + virtual const char * getAppName(); + virtual const char * getDefUserDirOptName(); + virtual const char * getDefCacheDirOptName(); + virtual const char * getDefOptionsOptName(); + virtual const char * getExtraClustersOptName(); + virtual const char * getJdkHomeOptName(); + virtual const char * getCurrentDir(); + virtual std::string constructApplicationDir(const std::string& dir, bool cache); + +private: + NbLauncher(const NbLauncher& orig); + bool readClusterFile(); + bool parseArgs(int argc, char *argv[]); + bool parseConfigFile(const char* path); + bool getOption(char *&str, const char *opt); + void addCluster(const char *cl); + void addExtraClusters(); + std::string getDefaultUserDirRoot(); + std::string getDefaultCacheDirRoot(); + +protected: + std::string baseDir; + std::string appName; + std::string platformDir; + std::string userHome; + std::string userDir; + std::string cacheDir; + std::string defUserDirRoot; + std::string defCacheDirRoot; + std::string clusters; + std::string extraClusters; + std::string nbOptions; + std::string jdkHome; + +private: + bool customUserDirFound; +}; + +#endif /* _NBLAUNCHER_H */ + diff --git a/nb/ide.launcher/windows/netbeans.cpp b/nb/ide.launcher/windows/netbeans.cpp new file mode 100644 index 000000000000..c14972f5d3e0 --- /dev/null +++ b/nb/ide.launcher/windows/netbeans.cpp @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + + +#include "nblauncher.h" + +int main(int argc, char *argv[]) { + NbLauncher launcher; + return launcher.start(argc - 1, argv + 1); +} diff --git a/nb/ide.launcher/windows/netbeans.exe.manifest b/nb/ide.launcher/windows/netbeans.exe.manifest new file mode 100644 index 000000000000..2dda7fb5081b --- /dev/null +++ b/nb/ide.launcher/windows/netbeans.exe.manifest @@ -0,0 +1,77 @@ + + + + + +NetBeans IDE process + + + + + + + + + + + + + + + + + UTF-8 + + + + + + + true/PM + PerMonitorV2, PerMonitor, system + + + + + + + + + + + + + diff --git a/nb/ide.launcher/windows/netbeans.ico b/nb/ide.launcher/windows/netbeans.ico new file mode 100644 index 0000000000000000000000000000000000000000..ec123c065723b8cb69bf2256eb52ace795dc8013 GIT binary patch literal 99678 zcmeHw2Y6FQw*Q6Hm)(?YZ#QrMyJY{Hyf1_l5)!g01mj-8HX#K9p_mdjKoU~eG`wU} z3C&05N9)&XCRw!}gI3xrC<=Fa*d8K^nO24{HR$NGC^A7*1w%)hkg`(fa z_}0d)^siH`3aHny_k`-$altCq?%=q(?LogaSB?)6dpq2-F2AeljXiOAu;}S_4po?Zj5T|VK>UJa2V-VI`+TXLoTOdcSt>JcVGynC1~2A z(zj=qwxRpp39eTbobRLQbUGPqI(|!)j@MizeL1^B+R8qCp%mZm|5$>~ zcWT1$`gvJd>R~M#-G_hZe!TIT%h}95Z)DNdKRrx)?-?EWepJTS?_`$Z`*4cy#c5gm zs#0{XtMAw9bghEHfig}Xzl_^b-D*euLiw%#Mrh2(PZJt&>e$Ph*|QrCg8j?!PO2Pl2v^ugZ( zJ#kQu3Y9Z*U#2R$EHf_X;%T$?LoNgD`)41U8lHP9bAEY7X4JKFX6;u!n;<0j69oM> zf{2}D+lH=1_n>=GJM$21KCq$oOaDU+kCT3mwnJmB-qCh!to8bgp&cA+-KN@6+@_M- zPrOfUM;)ynVI1Sf%))hd&kn1qDALC!I z{bdioK%>!hqrM2W|GehPZg%Fk1*|`rqvl7~d3{WSkGIg1^2qh# zeOxb2ah>F}rieqQ)<@0bdd#KGv{Q6kCppFS;*?x3-uKq;x$-wR4yEdW3-Gr%j&))E z!wU5alj5)5|Zf&pDn>wtKvf?H;Gt=242;U*Dzs@*{Ik%g?YHX}kf+fVH}A zJTDnI*V#^cjgc<@YVW)GIUB6Ezvx+Kj!!&2o7b=QJ#m& zgxyz{R%UmSpD|u5JR>>uRV1DIjD-0g{j4&(&7EECmz)KFAI zu9vz`ea6D|n|juw){pYxv}EnhdPV_TF73v2p#43p+JflvOf9uOYTo2C8YaTbvzjS7 zqG@O3Y1|fCdRGVSjmnF1YCY7vEzfwE4C=FGVmz#PCX>O8=FM%pfW z<^f1WIxjhIl84Nx*aYpI~10qm=>mE$;-@C}^Lr7jff*rL5f{ zKf^QLjFzqbliRlk+EuozFJ9qSN38I#`!&%0Iy~PM!KR;!2KomL^pDI-?+N7sA6q(h z1y3pX?s=khr+fKW=F23O`Z8f|pzdXm_Zgsjfc$)Ff_}t@2DU2TBL;Np0d_(J(Y764 z3XJ3LZJ$~q>bY{HE02K8w*k#PWV-Rb8Tv66O7`xMEZ`%kb!X6>9dRK<#+tib%EfZf zlhpyW#0tOKKLFk9LFQ;)M2qRArdH_3e29RD17I6ZHt+PG+_ua4IaoI z56~S2bkboPrqWBz+ekm=qXXu7K5LH){n1{FKR1&kFPeVHXx0U|&-vEt#b99HnQZ*Qn^eutdR>l+XcL;oB>Yi z7AbpQ^bmV@usK>S9d7|XK7{u6kKFyyMB9&ZZqTbWK^?@BS4tj*Hsuh|H)@{I9KHBB z(iPaWUo34Mpr;BY3b|T|=EJmF?Vy0)CgQhL>-f!;YHn$YjFbGn4Cek+fQKb|O`TJN zJrn{Dk(K{`@%FlJ;bji#xA5fxBJ`PYBF5L(7o0Mnw zcS{6a!)QJerf^1n*Xgeuc_-RhqvJQ04RQ02NZCi14~+C>HuIrr-WH%N`{Ko_{10Y4 zSn$zvB+8fK2wbv`;T8&PP z>Bi{|^y7ECtu>sb_nJv*s%Qtwo&xM z`~=XS0Q94|;&@%awEaU-&z_Sm^(jMR0u7cu(iN2d=AZ5T47yZ0tkeu+da0>d`t^K( zPPJ5Ncoi4>Ip;o;viC*~Q*8tKYyT&_6QY4SZ;Wo;ajf z@Q*CXa^ET?(5~6EuzB#}sXmEJtQrJ*jk-dm9px?4ZgWt`Tv8!l3 zS3jNOyz$#q7)MM^Q2Ph&mw$RLyQ^H(B>_Fxz~(5eChr3s)V0XPijz$xUHkW}5?$Un zbBMlSI(giQ_iY=0BDx<<(E7iyR}uWt5lQ%kQ_2Wfqs)DoLY6FbH*yw2x!p zrE@^8V}rl!aDJQY#MhCsy!W0_(?^e`t<(P~&^|q3C}`P1 zY1oOA1Mq%NGnYQ{?l*##g#2AK>q;;7U*I-NJLHmKBs+WU*MOg|HC#`uIhpQzoC^gLfSx0s{7L3*P+mU_@q;${gL)cddwz zHw#jfaSf%CYEjPs(kXMcfpn!E+MATlR_S_X{s7RdF-bRt7vMqnDkDSlZf1h=;E#(c zbKjfsVAe-3j+%dns69=D{(Rz5(2s+lE2I1rs5DdaU>7=M8!^|?6^ZRkX^TvxBF>fKfcb)A?6nTas%!7fPYRR5lv4bz_}B}_wMMjw5dV4Ns}T9&tWpHrlFZ9h=4=!1iVZB z8}RWB(8#CKX(?~esllkyG@&gzPQe24dwxD6-6!%|>K#!fX;$eqcR@(@aU$r_(c8dR zVP-^L@(G|>W{K`m=jf*gqf6676xuB5i5jjg1)0AUS(b4x*oZl@>^dHB`4kZjdKHqL z_+OwKksw<-&^bJcR};a842tO*=(|=AQaJ z=+t_kw*fZuwqYCnBA|Oe(EVh1N$TWzrKz@%GNx-nGmjHAY3+T#}Sve<&$g*^& z(lM68f-fZzk+job=coP%e0&Hzv;h4IL;E8Ix{pMcWz2{!$(RhWMPsSTrS}5;2#d*} zQ`2D_ax|(WH3!=NH=-D6_e6rOIQys5DW~WlG7p@U?ixvv!xG9HHgGPQjrPIO=zf&4 z!08C3vEWyPQbf>Zh>b$&6o`{TDa1;#PzrHVH%p57!hB-BjdB1+^>V>-!g7NPN6Qt< zc|`8WPs<0kSlEnyTIhhAfAH=c-u>54g6;7&0hRmCzyE0#H{O34Ygh2Su(_E!*HypN zw;CMh&VsK=^?w_DWSHPHGm!bw$6eqDCWCiti5+o4FE(%UzoT`B^L<@h$C>q#A*L8G zulp779Ss`|-m~ic4}kwc;J*|2$M4no;1BRU_>n!*zAJ1}y9fLAS?8Jnp9?1OwqGss zL;DBteH{3f;`hxcHNiiUgND63v=-vU|JlAX@DIAQbwu-y09&f_m}{2%))I^7R8Lyr z%ltd=jeLB#WWMpf8UC>@C_xu;AP#Tth>xdp{H9zfq$RVfh)<)r#PT^czXP3L1MlUl zfmfrC0p=U0R`|zqkboS11{plpxNXkuEj#>O$%4aWBVWn^4Z99CRZSagXa+yyRv1C@|Z4ih04Dfvj{FKDz_@y4VlYb-!@HGml zfY`{GmR$kAX+Jm@d{o_|4=d-?6EQEhf&XOf6ySR^@YX@)&syFA{;@77z^5`3;--T^ zAMS?DVZF8Y#y4ML5E~+ziDkZ34*=iGR{7U6fKTv;y1v$it@~r(AIm`qHgTYRSMc<@ ztv-{Rw!5~Uhyh<&Sd--Lm43_s;5`laRM^U^sq37;KavCT5o-fEd=BHMzjW*iBS1Io zh1KHqOMNSeH)mg)3_hz*K%1Tbya-J3W6v>YCv>a)VEpspM=<`e+m99FPfk_9cL~U0 z3HW{A&psGVG{oNMPic`+%E{&awZy`pD&!yiXXwv10e>y9+2!+UN+!rh@STtb)y_{k zx@%4!ZR8w!W57W_STg^3e*k2V0^=v&)*S(NwK))r5H+1atPN>I&nfo;-;2QC(HQ$+ ziXU5#>3s~rSMT2|TV+KT#lpb>wOHKE;&3Z2N;xTC2-$n1z<1v`7RLNIn)ZSmc6aO! zo>u*>-=vluwvC^bgN;L+&7HvaY~brGZ2h+KXYM-0H;fCkAHCKzaN%%|K-@bl*XjM` zw1c89R_BNxZp9Gy+G!Cx@m(?a8am>KYf4U97)v*SE_~FnGw{KVFJ==g3o$lJUMVHs zda3ZQz`NPl3v)c0JC1by-SCE?gWvFkoEC*xtJSH1cf$|!Z}j8U@*0X2oV)`9_K~+` z(APsuip_q!rufIlhM}CR?ck$a^VLhYH~wI{T?l*X1QGnikqxgtpCy4c9bo*{;IOS5 ze8yE<-|LW67s-UfLt4G>HRgOIrSPx!+X27R)@lu}hA!ize1bpo6)&&jtNXx6X%o2c)^q|2<_y0kP zSss-d_}{GeO9WqO|7rV_bDudaTr&F__}!cL`Np~rx~_dcx@j|0DP>az%TYy=EA;>{9`}O zcx~Y0KlRU_nJQQ|ryR9~H`oNS@wFih!||VUM6I<0B5>d_>pN~Y|JUW9<<%ATbF<_6 z*oPMNo9!=mhYrK~C8Cl~Ul4(hwtjsy;2Ha9IKaPA4&bYOL<(^Xf)#!>`nEyepTXGo zKWo~gB{>p-QlYWxd+sp*xNT^uR`aT|rJM_~LWny-{UweOP`7Rml$L+_vH*O%k*;e= zd^>@EBnPmG$Mz0|PfrvrnsrtD@#{_Uj1#>AsZeFJ@A}yIC$$aD6+^t@Uqqaw4dRa7 zVe*=pkego<1lmy3FMOKUQpfG{>WJrrLi4k67<5 zrO-C;>aWQv;@;-aHcZDhPUe@o?cbP+QS3^Ez~&e8nXn;RqlARAtD#bDW<)tz~! zeX?A}e>md5%v1PZ)d~1hc{P=H8vb7Xz4&|e-)sN&w)ms3cUJrFZT}`>`www|{lYF5 z*XB4J6Jw!~{(r*Zk768Tl3`_Er=+h3;&@OjwsKU=g$Z6wou6R*qc|W%ziLjBys z(*bLpi+WIuAG8fsqvNqWn}2B5P1yK#J+~T5p>GrL^>Sm|ATiZ8c#{4j8&|4TA`3Qd zAMaQONOw@%(8U(;+G^$Gw!uUAM>a08!^Rzz!${k}Lv2GfY8!OCCiMJ2{{6px{-cb~ z1I+tn4%@hcv1;f$2%>H=AGHn56;j4{^AB-gq0jG^UA)@V+&eTNhPa}Ue*C(=I*PAd z_jUG5mCaop+{^pkWx@OpHJ;7+^B*X7Z(71oK*WAgXxuUJ;{5aS11%MTdP!eD#3eaB z_Ha}?NRlmzd*bvUJwf`WS^W@4=KT3j9BcW?K56imM+6b+ zr<4$frbV$d;18}|TaqO`$8Hp~%f(KKT{O?POb5EAE*JMmx3yIW->ST%)W_JNIJEK% z_3Fz9qhd-;N zi|E~K5w~ADY)j0bIX+DtN3n&CGGYHQZbRRyn%sWyUB4mj3dQ3=jOXyilpjSW|1(bn zF`mPe7*E^h|G>umo=8vzzV?$a^rsV&xw*+|D&LrYoPr#*Zxoyx++JTIs1$ZfK?Z7b zF^8sjG<6KcCU(H{L3($)@PqmS$%67swY9h{6kEBd@a$mh@lORQpZQ8b25Li$sAc}A z!dgjF6ZG#tA+A^)^21S4#Koi`TVpPf91QVgniWN9@?&ka0$Bf8AA4zvH%rG1a#Ixw z_~I?irJ^@0E)Llf+lX{wetDK=IqjHyN5VS-h|2_$fo$B4 zShrDea7Ydd80qSFGxqc!`r(bTybVwPG2@e$N4@vOnb6}Wh>-YWe~rk2*eQB)H+1P|y-no;rnpZ|?k|x% zASQMwyO%B6)KDaTtvpKwah9WSw1G!c*Mr_v4^S{(#IodEd}qYSt8I%FeJG1Z^_$An3cQOw=v;p|xDNXrwqE0o5}}t* z-UV_9fSBb};9W5m{-KQ>j4nwX_1ys*c_rhH`i3^p_0OWp(*F`w4mJ)ktFHR_rzAt$ zkO*=(^+0%T(o$#}%0LEchvYDJ{)NCdiZOmFn4UU$ZlUY=rphxEVsry89Yby8UqKhX zgtn~%WME(0;5h#fho6}N?Rqe@>vse0RPx3xADEp;%(-;(Hju+J&^8kwpvjn9Qx^Lt<%Ggh+3{r=#K zCy2nbqql<`o(Ekx4lv|j&R^riQ=}C}OCmz^lP87eoq8N>VsBJ&Y8Ke|(kKS3 zOT!rdHXZy?lvCgjerN#!^rOQUU(gRNFaSSTnP4_b^$QR{%7XP5P(Btd)Bryu+0FXP zV4(&m1?AEAX;6y3QG-$feWwQfWO?|3>^#TL9njV8sRg zP#pXGeKu9#y~tA~Fd4qlNE^ON# z@GONiZ`OqpSm0Clrxkw8BQfv|Pn#l$(CyU^gEN~$1v9emU+G)FeU*RRuq!dPRJObDM|uG3dJn@p#_f#nX22Ja zZmHj7u=iE4R(h``Y{ui9JMlNR1-nCfJ9dSv0u8w7-!m_pQ!_ippIJE`*xFKuC*Y6u z0NyE7cEknDz8PDBr9PDp!Mq(>cV6d7nU+w$|yX_~W(!)`RE6_Z=34 z4on#5{UyFtGr``AZN(?F_4ZmS6`X=&G}hjTfzdKIyxaAlwgKKN^~1OE zKBvV#bho?p0Ai>XfX|)X-w1Ry&Zf#w{E=G-i>EuZeuy0bs@IU({%vR z2RdDy_}3o*jLm-k)>H6*e{N%6Tea*8;H@EJPTn_%zd;W)?2-#tSo@>< zJYEmtLNu(npaU)6%=&{X^k4?D{|@l0-v~Aj-wgAtIUFiIYXa+rvy;2&fU|^*wW)n8 z`0M)wUQ4Bfl^suK#fQQ7_B?MqK&A=eSS75TK^yn4BJOaO9>mP43579z6IIThnBVs) zt88dc(`E{5Q^#z<-`FQKm9??Yd{{=7x2NvITyhg@S3syUbRcNjq0%L@OWQpWZ%or? z3maL&uAvfB7+X4K5B^vWc(wGBjzf!Bo{Bx93;Kfg(l1^pbq4&Af^GvLzZwhcg_*~ksk1xs)o2lr{H;UE_~0`bNU2$CXm+tXEu$t z{%QR;BAtc*$hSjbo$#p%z4K>gT>)R6G5g++MSsv7)44tT0*yx3V-8zejysCKu`Ot> z>|v*UTL5$Q_t^QZ8eDF*!`TLko#~<2)5nb3@w`f*j%~&vW^xm!S zwAK#FRZLs(wRX)|@yB|=tt)1-PpqkRM_bUoE4b#`rkQnQ-0{Ba@YnYV+K?xIzPi+> zqRUY%?YVDbR8u#vRZ#$#!sjWR^K%yd20hU7Dzge$`xkVNhaSKfudCwAm#@;+oBSq# z{yPz_#2@zwevifX&zo_U2J^p4d+@aN+INEMl?CVfXn;8SzPwX^PR4)ad9kTd&Y}H8 zgXcx1EA#+xSJr>)L(6+_dOx;vbLn{CkM+R+v3=~<|8d!=@BNN^#VJ+~X<1GMom7}B z@W*`uud$rPO8Hl@Gj*V4M__TmN6)g&;Y~e0zW9%f4FVrOP`+e#af_|?ZR)z%#Vsw8 zzF`IlDwpiK5`Uu})DbES$?@(aCVUzEfiJz&L!ifgvKLeG2eX_Yms zO`Ufa{B9~^z4S&P?Mfk3pfPHC4 zK07W{V?__tOF+-yFomnF$J~v-Q4gl=Yh3tJfl0sL9q+eQDF-!;E(O|5;p2_J zu}^3yZDb|BTV+ZI+IIw17Jl?xqpcWQy3SMZ$9fR-_|HXe&#B-co8PpciPz0i6q$i$ zTn@Vnf2;?{_lW(|>pZ<4><;0TfAM0GB|Pmt=V|yOJ@B0xuQ>coWf}mi7#EN&RN`*@ zksiSNMMd+OFVdi`SJ;cMwd*|*f20Gnlm?mwSjO#?C*Y5Cpdo7?%^H@DocH2yS(Uu_ zTh|cWcRMrn+W&~ZAsz>K?ccJUy6UXg{=N2(ZP1;m*Zy5);g-ww+P~NS-D&r@Zm<1Y zwo_M~_1eGJ{;>_ZGxgfPt1R4dxnBGC+P^#P9@p))f6I32s=qJ2ll8= zFaBo0a_-?a!JwiPV{R(t^zuqOTWZ?ITMxYWI~QnjXpi z99}yet@|`ydf>&MjF{8*)q|?xe15-7K*iXWJXb0faM|_w{FX|!tM$N(ztb?+7X*EL zd5=QgYzxlTuHlM%oB6FZ<*w8LFaFNKAKH4Ba7a;X4O2(Xb9;Ej&?m55p$A_4$Be&J zp;FPHj~{XbTU+mevB40pvx5fDi&AImffs*=@z+2ff2DIk-fJs{PPtAd?&Y@EUjZG^ zI71J-_}h=aMysvt9h5gZ1y9mkfL-N@dK-By)ssJlaI0G`JCt;6i;q*(DJYFk}*IXsDR}Z}STf|>8tW{m< z?3edoS$lHIl?r?89UFM@H;q5^@zuQp@_J9k+bnIu?s{%(b+s*RffxT9@aMvFe34n% z+So69!u{-Sb`h_+nrlf9y!adO??-(+JjV}u0(Q=#0mcS{Ty6`E-&ECaN)NpF>$JmK zbpiD8UCxrZCzivO3c7f#x&qJvEm;q4W&E`|ZB5^xoau>pxr!#fu#3rStFFO1a4X^u zbM>8~Aw{99WIPedg|R^)x2dx8R>B{x|MtTndJ5p<(0kd5fU8|J%B6yow1gDehNo}( z_1}D--BT2jc$_zvmaJQRHI-K);NKKue7o=_J-d_%yNi}p=kQ)F&(tlV9pjz;)bFNT z|IzpHgvP+{4^<)DsoRGYxmB%Fp?l}?Ntif_r9Jnx%0!Ku8Vair?$m9~FI%fFZM-?w ze?{v*`!3y=ACYrPL&cq(kH|~X>}#&b=R#X(j~pl3wTQp{?7I9{%QG}o+{yX*j8x56 zd*98^*)TEJe@5%S&+&<;hg~=+CgW^v|5f@~$>q)tI^e3BXxLhzSC!q%p}$#iSwhCy z+Wu<=XT*oLL{6yn-+iBqFAq9+ti>AEmd?jq%WA2U^f9c+)abwM$=B6M1dO#zdW$uz zEuCL->8F;|k6!fX??3oGmcS0!bgb@WSE-?Wt%Tf)`e za~qF+QJlSDhDUw>1%3Z%PSjpnSk@_}z4+R8{b}W?js_Z6E|Hs)wI>~iK3;yhvxT;x zB1>s6zP4OHzcf|3WBc2*+zsyi{u6u?RO|bE!qw2^<6XAlc;ndLp8MV`INyD(hhG3# zYdr~X5-r+mqOO9st8%(+!EvnDyg@(FmGpUlTfYD1J1wCuVEf@3d+>ACwd+eS*S1K7 z9yMRwA{Q|?))&@}6;nsnijynyRg%7vm9=>+XW-?kG8SJx)PCWUSx))>dqi$h2yBhc zz{%BRd|sJf)-IE@xdL}o?&ijlGFM^d%yQ?KWi&>XrG{8v-NUvkW~|zOM_6v+doWLH z*L?#EeGz%dYLl`z@qWi$*S(&f(wE=G$p;@XIkQ}_`Sz&N z3(;dkaO`(K92a+2cwXYaU~C}Avi8(8GXKm#3a1%8FDl4-fb!=%+i9;cvId-qkt@oY zU!E?HF3tEClKa@vb6yES7xzC1EE~zYrAyAl$W>)UGcvD57NyK|K3Xm- zaZ-5B$we?vtoQZvR2`Ui?L5s@m^q_d=;L`&rD=-*rAaPB%7q0#d2H*iB65n&hw>0CGafHK7RmDyY%}t7dXN4Yj>wzcW4`aKYXhvELLBvjW z6CiG>_W2WW_l4!2+6wK#u)FlYo%n;j55xFwYe?pa``iM6hg2GH`Q#(vxk;(+&;fVh zA6=G_8eW|Ch=)Mn5oCnqCIyDmlIq7(55^mRct2Mk$w&+I2!VSd5wWqi!+Yj+;dx1- z@z8_u!XMgsQ8XiU9Rd7#qS!r+Cckq>e+P30dtCjV+12<1?rQMG*yERT^mm>n0IMHbhyL55}v;|kk(iV&re|V0+8d;n&W1`D)BGV6g@CH09a2(MC zNAU;TIZ%@Jw)@41=eceC&kcck~_f3qw>rFoi$N+YLcm{~fyT zW|PIO%n!U@{5!l~Od;z46@Qq!O9^45{QXvz)6LF%Sk6g*(1Ti}2N-`C)7Q=`OZUIo zdH3>Xkidckw?*V6u8l0Za2nprt|bM6$0FX(ra_m9rAZX2DCB}V17 z1TmX@Kur)+$ax7t+(pjQ!JD0&j|I__@=)BU0+lFFqKJj^B#P)LPbv^)31TxY5vW1G zDL4<*pr4TIy8Hv06jG*Z=lFfoUuSUI){D+ibgW%e={n;Kn==I zL3v|wh5}jW%*apAVl2)q!M}*5{2B8QN1LMTQ34SfHUj zrnc8ciu9$ypMfG{2VyAD*dG`unu4!4P_)^Y*HdJm1|8HFXe`dqq?7t9YJaAu$XFWe nK!K#<^g=gMgRTRLrl1u6pupL9U!PL?V;!}>ruOH?{{H^}KEHS1 literal 0 HcmV?d00001 diff --git a/nb/ide.launcher/windows/netbeans.rc b/nb/ide.launcher/windows/netbeans.rc new file mode 100644 index 000000000000..348a32085aba --- /dev/null +++ b/nb/ide.launcher/windows/netbeans.rc @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include + +#include "version.rc" + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. + +100 ICON "netbeans.ico" + +// Value MANIFEST_FILE id taken from windres parameter -DMANIFEST_FILE +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST MANIFEST_FILE + diff --git a/nb/ide.launcher/windows/netbeans64.exe.manifest b/nb/ide.launcher/windows/netbeans64.exe.manifest new file mode 100644 index 000000000000..b1d9a5f31d98 --- /dev/null +++ b/nb/ide.launcher/windows/netbeans64.exe.manifest @@ -0,0 +1,77 @@ + + + + + + +NetBeans IDE process + + + + + + + + + + + + + + + + + UTF-8 + + + + + + true/PM + PerMonitorV2, PerMonitor, system + + + + + + + + + + + + + diff --git a/nb/ide.launcher/windows/version.h b/nb/ide.launcher/windows/version.h new file mode 100644 index 000000000000..b1667b9caf7c --- /dev/null +++ b/nb/ide.launcher/windows/version.h @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#define COMPANY "" +#define COMPONENT "NetBeans IDE" +#define VER "12.5.0.0" +#define FVER 12,5,0,0 +#define BUILD_ID "28062021" +#define INTERNAL_NAME "netbeans" +#define COPYRIGHT "Based on Apache NetBeans from the Apache Software Foundation and is licensed under Apache License Version 2.0" +#define NAME "NetBeans IDE 12.5" + diff --git a/nb/ide.launcher/windows/version.rc b/nb/ide.launcher/windows/version.rc new file mode 100644 index 000000000000..0bb79bf4688a --- /dev/null +++ b/nb/ide.launcher/windows/version.rc @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include "version.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION FVER + PRODUCTVERSION FVER + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + // FILEOS 0x4 is Win32, 0x40004 is Win32 NT only + FILEOS 0x4L + // FILETYPE should be 0x1 for .exe and 0x2 for .dll + FILETYPE 0x1 + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", COMPANY "\0" + VALUE "FileDescription", COMPONENT "\0" + VALUE "FileVersion", VER "\0" + VALUE "Full Version", BUILD_ID "\0" + VALUE "InternalName", INTERNAL_NAME "\0" + VALUE "LegalCopyright", COPYRIGHT "\0" + VALUE "ProductName", NAME "\0" + VALUE "ProductVersion", VER "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/platform/o.n.bootstrap/launcher/windows/Makefile.mingw b/platform/o.n.bootstrap/launcher/windows/Makefile.mingw new file mode 100644 index 000000000000..0fd8e394f75c --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/Makefile.mingw @@ -0,0 +1,52 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +TMPFLD = ../../../../target/tmp/ +OFLD = ../../../../target/bootstrap/ + +all: prepfolder nbexec64.dll nbexec64.exe nbexec.dll nbexec.exe + +prepfolder: + mkdir -p $(TMPFLD) + mkdir -p $(OFLD) + +clean: + rm -f *.res *.exe *.dll + +nbexec64.res: nbexec.rc + x86_64-w64-mingw32-windres -o$(TMPFLD)nbexec64.res -Ocoff nbexec.rc + +nbexec64.dll: include/jni.h include/jni_types.h jvmlauncher.cpp nbexec.cpp platformlauncher.cpp utilsfuncs.cpp nbexec64.res + x86_64-w64-mingw32-gcc -s -shared -m64 -o $(OFLD)nbexec64.dll -I include jvmlauncher.cpp nbexec.cpp platformlauncher.cpp utilsfuncs.cpp $(TMPFLD)nbexec64.res -Wl,--no-insert-timestamp -static -lstdc++ -static-libstdc++ -static-libgcc + +nbexec_exe64.res: nbexec_exe.rc nbexec.exe.manifest + x86_64-w64-mingw32-windres -o$(TMPFLD)nbexec_exe64.res -Ocoff -DMANIFEST_FILE=nbexec.exe.manifest nbexec_exe.rc + +nbexec64.exe: nbexecexe.cpp utilsfuncs.cpp nbexec_exe64.res + x86_64-w64-mingw32-gcc -s -DNBEXEC_DLL='"nbexec64.dll"' -DARCHITECTURE=64 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -Wl,--no-insert-timestamp -mwindows nbexecexe.cpp utilsfuncs.cpp $(TMPFLD)nbexec_exe64.res -o$(OFLD)nbexec64.exe -static -lstdc++ -static-libstdc++ -static-libgcc + +nbexec.res: nbexec.rc + i686-w64-mingw32-windres -o$(TMPFLD)nbexec.res -Ocoff nbexec.rc + +nbexec.dll: include/jni.h include/jni_types.h jvmlauncher.cpp nbexec.cpp platformlauncher.cpp utilsfuncs.cpp nbexec.res + i686-w64-mingw32-gcc -s -shared -o $(OFLD)nbexec.dll -I include jvmlauncher.cpp nbexec.cpp platformlauncher.cpp utilsfuncs.cpp $(TMPFLD)nbexec.res -static -Wl,--no-insert-timestamp -lstdc++ -static-libstdc++ -static-libgcc + +nbexec_exe.res: nbexec_exe.rc nbexec.exe.manifest + i686-w64-mingw32-windres -o$(TMPFLD)nbexec_exe.res -Ocoff -DMANIFEST_FILE=nbexec.exe.manifest nbexec_exe.rc + +nbexec.exe: nbexecexe.cpp utilsfuncs.cpp nbexec_exe.res + i686-w64-mingw32-gcc -s -DNBEXEC_DLL='"nbexec.dll"' -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -Wl,--no-insert-timestamp -mwindows nbexecexe.cpp utilsfuncs.cpp $(TMPFLD)nbexec_exe.res -o$(OFLD)nbexec.exe -static -lstdc++ -static-libstdc++ -static-libgcc diff --git a/platform/o.n.bootstrap/launcher/windows/argnames.h b/platform/o.n.bootstrap/launcher/windows/argnames.h new file mode 100644 index 000000000000..c4bdaba2353f --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/argnames.h @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _ARGNAMES_H +#define _ARGNAMES_H + +#define ARG_NAME_SEPAR_PROC "--fork-java" +#define ARG_NAME_CONSOLE "--console" +#define ARG_NAME_LAUNCHER_LOG "--trace" +#define ARG_NAME_LA_START_APP "--la_start_app" +#define ARG_NAME_LA_START_AU "--la_start_au" +#define ARG_NAME_LA_PPID "--la_ppid" +#define ARG_NAME_USER_DIR "--userdir" +#define ARG_DEFAULT_USER_DIR_ROOT "--default_userdir_root" +#define ARG_NAME_CACHE_DIR "--cachedir" +#define ARG_NAME_CLUSTERS "--clusters" +#define ARG_NAME_BOOTCLASS "--bootclass" +#define ARG_NAME_JDKHOME "--jdkhome" +#define ARG_NAME_CP_PREPEND "--cp:p" +#define ARG_NAME_CP_APPEND "--cp:a" +#define ARG_NAME_NOSPLASH "--nosplash" + + +#endif /* _ARGNAMES_H */ + diff --git a/platform/o.n.bootstrap/launcher/windows/include/README b/platform/o.n.bootstrap/launcher/windows/include/README new file mode 100644 index 000000000000..7641ada3b1fd --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/include/README @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +These header files originate in the Apache Harmony project, tag 5.0m12a. diff --git a/platform/o.n.bootstrap/launcher/windows/include/jni.h b/platform/o.n.bootstrap/launcher/windows/include/jni.h new file mode 100644 index 000000000000..16cf67b457b4 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/include/jni.h @@ -0,0 +1,1838 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file + * This file describes the JNI interface as per the JNI + * specification 1.5 available from Sun + * + * See specification + * for details. + */ + +#ifndef _JNI_H_ +#define _JNI_H_ + +#include +#include +#include "jni_types.h" + +/* + * Supported JNI versions + */ +/** + * Constant which specifies JNI interface version 1.1 + */ +#define JNI_VERSION_1_1 0x00010001 +/** + * Constant which specifies JNI interface version 1.2 + */ +#define JNI_VERSION_1_2 0x00010002 +/** + * Constant which specifies JNI interface version 1.4 + */ +#define JNI_VERSION_1_4 0x00010004 + +/** + * JNI Native Method Interface table for use in C sources + * + * See specification + * for details + */ +struct JNINativeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + void *reserved3; + + jint (JNICALL *GetVersion)(JNIEnv *env); + + jclass (JNICALL *DefineClass) + (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len); + jclass (JNICALL *FindClass) + (JNIEnv *env, const char *name); + + jmethodID (JNICALL *FromReflectedMethod) + (JNIEnv *env, jobject method); + jfieldID (JNICALL *FromReflectedField) + (JNIEnv *env, jobject field); + jobject (JNICALL *ToReflectedMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); + + jclass (JNICALL *GetSuperclass) + (JNIEnv *env, jclass sub); + jboolean (JNICALL *IsAssignableFrom) + (JNIEnv *env, jclass sub, jclass sup); + jobject (JNICALL *ToReflectedField) + (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); + + jint (JNICALL *Throw) + (JNIEnv *env, jthrowable obj); + jint (JNICALL *ThrowNew) + (JNIEnv *env, jclass clazz, const char *msg); + jthrowable (JNICALL *ExceptionOccurred) + (JNIEnv *env); + void (JNICALL *ExceptionDescribe) + (JNIEnv *env); + void (JNICALL *ExceptionClear) + (JNIEnv *env); + void (JNICALL *FatalError) + (JNIEnv *env, const char *msg); + + jint (JNICALL *PushLocalFrame) + (JNIEnv *env, jint cap); + jobject (JNICALL *PopLocalFrame) + (JNIEnv *env, jobject res); + + jobject (JNICALL *NewGlobalRef) + (JNIEnv *env, jobject lobj); + void (JNICALL *DeleteGlobalRef) + (JNIEnv *env, jobject gref); + void (JNICALL *DeleteLocalRef) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsSameObject) + (JNIEnv *env, jobject obj1, jobject obj2); + + jobject (JNICALL *NewLocalRef) + (JNIEnv *env, jobject ref); + jint (JNICALL *EnsureLocalCapacity) + (JNIEnv *env, jint); + + jobject (JNICALL *AllocObject) + (JNIEnv *env, jclass clazz); + jobject (JNICALL *NewObject) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *NewObjectV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *NewObjectA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jclass (JNICALL *GetObjectClass) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsInstanceOf) + (JNIEnv *env, jobject obj, jclass clazz); + + jmethodID (JNICALL *GetMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallObjectMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jobject (JNICALL *CallObjectMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jobject (JNICALL *CallObjectMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); + + jboolean (JNICALL *CallBooleanMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jboolean (JNICALL *CallBooleanMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jboolean (JNICALL *CallBooleanMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); + + jbyte (JNICALL *CallByteMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jbyte (JNICALL *CallByteMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jbyte (JNICALL *CallByteMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jchar (JNICALL *CallCharMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jchar (JNICALL *CallCharMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jchar (JNICALL *CallCharMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jshort (JNICALL *CallShortMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jshort (JNICALL *CallShortMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jshort (JNICALL *CallShortMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jint (JNICALL *CallIntMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jint (JNICALL *CallIntMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jint (JNICALL *CallIntMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jlong (JNICALL *CallLongMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jlong (JNICALL *CallLongMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jlong (JNICALL *CallLongMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jfloat (JNICALL *CallFloatMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jfloat (JNICALL *CallFloatMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jfloat (JNICALL *CallFloatMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + jdouble (JNICALL *CallDoubleMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jdouble (JNICALL *CallDoubleMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jdouble (JNICALL *CallDoubleMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + void (JNICALL *CallVoidMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + void (JNICALL *CallVoidMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + void (JNICALL *CallVoidMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); + + jobject (JNICALL *CallNonvirtualObjectMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallNonvirtualObjectMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jobject (JNICALL *CallNonvirtualObjectMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args); + + jboolean (JNICALL *CallNonvirtualBooleanMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallNonvirtualBooleanMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jboolean (JNICALL *CallNonvirtualBooleanMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args); + + jbyte (JNICALL *CallNonvirtualByteMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallNonvirtualByteMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jbyte (JNICALL *CallNonvirtualByteMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jchar (JNICALL *CallNonvirtualCharMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallNonvirtualCharMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jchar (JNICALL *CallNonvirtualCharMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jshort (JNICALL *CallNonvirtualShortMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallNonvirtualShortMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jshort (JNICALL *CallNonvirtualShortMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jint (JNICALL *CallNonvirtualIntMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallNonvirtualIntMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jint (JNICALL *CallNonvirtualIntMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jlong (JNICALL *CallNonvirtualLongMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallNonvirtualLongMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jlong (JNICALL *CallNonvirtualLongMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jfloat (JNICALL *CallNonvirtualFloatMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallNonvirtualFloatMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jfloat (JNICALL *CallNonvirtualFloatMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + jdouble (JNICALL *CallNonvirtualDoubleMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallNonvirtualDoubleMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jdouble (JNICALL *CallNonvirtualDoubleMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + void (JNICALL *CallNonvirtualVoidMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + void (JNICALL *CallNonvirtualVoidMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + void (JNICALL *CallNonvirtualVoidMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args); + + jfieldID (JNICALL *GetFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *GetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jboolean (JNICALL *GetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jbyte (JNICALL *GetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jchar (JNICALL *GetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jshort (JNICALL *GetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jint (JNICALL *GetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jlong (JNICALL *GetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jfloat (JNICALL *GetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jdouble (JNICALL *GetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + + void (JNICALL *SetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); + void (JNICALL *SetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); + void (JNICALL *SetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); + void (JNICALL *SetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); + void (JNICALL *SetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); + void (JNICALL *SetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); + void (JNICALL *SetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); + void (JNICALL *SetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); + void (JNICALL *SetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); + + jmethodID (JNICALL *GetStaticMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallStaticObjectMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallStaticObjectMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *CallStaticObjectMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jboolean (JNICALL *CallStaticBooleanMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallStaticBooleanMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jboolean (JNICALL *CallStaticBooleanMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jbyte (JNICALL *CallStaticByteMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallStaticByteMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jbyte (JNICALL *CallStaticByteMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jchar (JNICALL *CallStaticCharMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallStaticCharMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jchar (JNICALL *CallStaticCharMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jshort (JNICALL *CallStaticShortMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallStaticShortMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jshort (JNICALL *CallStaticShortMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jint (JNICALL *CallStaticIntMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallStaticIntMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jint (JNICALL *CallStaticIntMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jlong (JNICALL *CallStaticLongMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallStaticLongMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jlong (JNICALL *CallStaticLongMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jfloat (JNICALL *CallStaticFloatMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallStaticFloatMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jfloat (JNICALL *CallStaticFloatMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + jdouble (JNICALL *CallStaticDoubleMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallStaticDoubleMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jdouble (JNICALL *CallStaticDoubleMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + void (JNICALL *CallStaticVoidMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, ...); + void (JNICALL *CallStaticVoidMethodV) + (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); + void (JNICALL *CallStaticVoidMethodA) + (JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args); + + jfieldID (JNICALL *GetStaticFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + jobject (JNICALL *GetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jboolean (JNICALL *GetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jbyte (JNICALL *GetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jchar (JNICALL *GetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jshort (JNICALL *GetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jint (JNICALL *GetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jlong (JNICALL *GetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jfloat (JNICALL *GetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jdouble (JNICALL *GetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + + void (JNICALL *SetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); + void (JNICALL *SetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); + void (JNICALL *SetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); + void (JNICALL *SetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); + void (JNICALL *SetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); + void (JNICALL *SetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); + void (JNICALL *SetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); + void (JNICALL *SetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); + void (JNICALL *SetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); + + jstring (JNICALL *NewString) + (JNIEnv *env, const jchar *unicode, jsize len); + jsize (JNICALL *GetStringLength) + (JNIEnv *env, jstring str); + const jchar *(JNICALL *GetStringChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringChars) + (JNIEnv *env, jstring str, const jchar *chars); + + jstring (JNICALL *NewStringUTF) + (JNIEnv *env, const char *utf); + jsize (JNICALL *GetStringUTFLength) + (JNIEnv *env, jstring str); + const char* (JNICALL *GetStringUTFChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringUTFChars) + (JNIEnv *env, jstring str, const char* chars); + + + jsize (JNICALL *GetArrayLength) + (JNIEnv *env, jarray array); + + jobjectArray (JNICALL *NewObjectArray) + (JNIEnv *env, jsize len, jclass clazz, jobject init); + jobject (JNICALL *GetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index); + void (JNICALL *SetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index, jobject val); + + jbooleanArray (JNICALL *NewBooleanArray) + (JNIEnv *env, jsize len); + jbyteArray (JNICALL *NewByteArray) + (JNIEnv *env, jsize len); + jcharArray (JNICALL *NewCharArray) + (JNIEnv *env, jsize len); + jshortArray (JNICALL *NewShortArray) + (JNIEnv *env, jsize len); + jintArray (JNICALL *NewIntArray) + (JNIEnv *env, jsize len); + jlongArray (JNICALL *NewLongArray) + (JNIEnv *env, jsize len); + jfloatArray (JNICALL *NewFloatArray) + (JNIEnv *env, jsize len); + jdoubleArray (JNICALL *NewDoubleArray) + (JNIEnv *env, jsize len); + + jboolean * (JNICALL *GetBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *isCopy); + jbyte * (JNICALL *GetByteArrayElements) + (JNIEnv *env, jbyteArray array, jboolean *isCopy); + jchar * (JNICALL *GetCharArrayElements) + (JNIEnv *env, jcharArray array, jboolean *isCopy); + jshort * (JNICALL *GetShortArrayElements) + (JNIEnv *env, jshortArray array, jboolean *isCopy); + jint * (JNICALL *GetIntArrayElements) + (JNIEnv *env, jintArray array, jboolean *isCopy); + jlong * (JNICALL *GetLongArrayElements) + (JNIEnv *env, jlongArray array, jboolean *isCopy); + jfloat * (JNICALL *GetFloatArrayElements) + (JNIEnv *env, jfloatArray array, jboolean *isCopy); + jdouble * (JNICALL *GetDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jboolean *isCopy); + + void (JNICALL *ReleaseBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); + void (JNICALL *ReleaseByteArrayElements) + (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); + void (JNICALL *ReleaseCharArrayElements) + (JNIEnv *env, jcharArray array, jchar *elems, jint mode); + void (JNICALL *ReleaseShortArrayElements) + (JNIEnv *env, jshortArray array, jshort *elems, jint mode); + void (JNICALL *ReleaseIntArrayElements) + (JNIEnv *env, jintArray array, jint *elems, jint mode); + void (JNICALL *ReleaseLongArrayElements) + (JNIEnv *env, jlongArray array, jlong *elems, jint mode); + void (JNICALL *ReleaseFloatArrayElements) + (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); + void (JNICALL *ReleaseDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); + + void (JNICALL *GetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *GetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *GetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *GetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *GetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *GetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *GetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *GetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + void (JNICALL *SetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *SetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *SetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *SetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *SetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *SetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *SetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *SetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + jint (JNICALL *RegisterNatives) + (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods); + jint (JNICALL *UnregisterNatives) + (JNIEnv *env, jclass clazz); + + jint (JNICALL *MonitorEnter) + (JNIEnv *env, jobject obj); + jint (JNICALL *MonitorExit) + (JNIEnv *env, jobject obj); + + jint (JNICALL *GetJavaVM) + (JNIEnv *env, JavaVM **vm); + + void (JNICALL *GetStringRegion) + (JNIEnv *env, jstring, jsize, jsize, jchar*); + void (JNICALL *GetStringUTFRegion) + (JNIEnv *env, jstring, jsize, jsize, char*); + + void* (JNICALL *GetPrimitiveArrayCritical) + (JNIEnv *env, jarray array, jboolean *isCopy); + void (JNICALL *ReleasePrimitiveArrayCritical) + (JNIEnv *env, jarray array, void* carray, jint mode); + + const jchar* (JNICALL *GetStringCritical) + (JNIEnv *env, jstring s, jboolean* isCopy); + void (JNICALL *ReleaseStringCritical) + (JNIEnv *env, jstring s, const jchar* cstr); + + jweak (JNICALL *NewWeakGlobalRef) + (JNIEnv *env, jobject obj); + void (JNICALL *DeleteWeakGlobalRef) + (JNIEnv *env, jweak obj); + + jboolean (JNICALL *ExceptionCheck) + (JNIEnv *env); + + jobject (JNICALL *NewDirectByteBuffer) + (JNIEnv* env, void* address, jlong capacity); + void* (JNICALL *GetDirectBufferAddress) + (JNIEnv* env, jobject buf); + jlong (JNICALL *GetDirectBufferCapacity) + (JNIEnv* env, jobject buf); +}; + + +/** + * JNI Native Method Interface table for use in C++ sources + * + * See specification + * for details + */ +struct JNIEnv_External { + const struct JNINativeInterface_ *functions; + +#ifdef __cplusplus + jint GetVersion() { + return functions->GetVersion(this); + } + jclass DefineClass(const char *name, jobject loader, const jbyte *buf, + jsize len) { + return functions->DefineClass(this, name, loader, buf, len); + } + jclass FindClass(const char *name) { + return functions->FindClass(this, name); + } + jmethodID FromReflectedMethod(jobject method) { + return functions->FromReflectedMethod(this, method); + } + jfieldID FromReflectedField(jobject field) { + return functions->FromReflectedField(this, field); + } + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { + return functions->ToReflectedMethod(this, cls, methodID, isStatic); + } + jclass GetSuperclass(jclass sub) { + return functions->GetSuperclass(this, sub); + } + jboolean IsAssignableFrom(jclass sub, jclass sup) { + return functions->IsAssignableFrom(this, sub, sup); + } + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { + return functions->ToReflectedField(this, cls, fieldID, isStatic); + } + + jint Throw(jthrowable obj) { + return functions->Throw(this, obj); + } + jint ThrowNew(jclass clazz, const char *msg) { + return functions->ThrowNew(this, clazz, msg); + } + jthrowable ExceptionOccurred() { + return functions->ExceptionOccurred(this); + } + void ExceptionDescribe() { + functions->ExceptionDescribe(this); + } + void ExceptionClear() { + functions->ExceptionClear(this); + } + void FatalError(const char *msg) { + functions->FatalError(this, msg); + } + + jint PushLocalFrame(jint cap) { + return functions->PushLocalFrame(this, cap); + } + jobject PopLocalFrame(jobject res) { + return functions->PopLocalFrame(this, res); + } + + jobject NewGlobalRef(jobject lobj) { + return functions->NewGlobalRef(this,lobj); + } + void DeleteGlobalRef(jobject gref) { + functions->DeleteGlobalRef(this,gref); + } + void DeleteLocalRef(jobject obj) { + functions->DeleteLocalRef(this, obj); + } + + jboolean IsSameObject(jobject obj1, jobject obj2) { + return functions->IsSameObject(this,obj1,obj2); + } + jobject NewLocalRef(jobject ref) { + return functions->NewLocalRef(this, ref); + } + + jint EnsureLocalCapacity(jint cap) { + return functions->EnsureLocalCapacity(this,cap); + } + + jobject AllocObject(jclass clazz) { + return functions->AllocObject(this,clazz); + } + jobject NewObject(jclass clazz, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args, methodID); + result = functions->NewObjectV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject NewObjectV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->NewObjectV(this,clazz,methodID,args); + } + jobject NewObjectA(jclass clazz, jmethodID methodID, + jvalue *args) { + return functions->NewObjectA(this,clazz,methodID,args); + } + + jclass GetObjectClass(jobject obj) { + return functions->GetObjectClass(this,obj); + } + jboolean IsInstanceOf(jobject obj, jclass clazz) { + return functions->IsInstanceOf(this,obj,clazz); + } + + jmethodID GetMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetMethodID(this,clazz,name,sig); + } + + jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallObjectMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jobject CallObjectMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallObjectMethodV(this,obj,methodID,args); + } + jobject CallObjectMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallObjectMethodA(this,obj,methodID,args); + } + + jboolean CallBooleanMethod(jobject obj, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallBooleanMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallBooleanMethodV(this,obj,methodID,args); + } + jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallBooleanMethodA(this,obj,methodID, args); + } + + jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallByteMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jbyte CallByteMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallByteMethodV(this,obj,methodID,args); + } + jbyte CallByteMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallByteMethodA(this,obj,methodID,args); + } + + jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallCharMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jchar CallCharMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallCharMethodV(this,obj,methodID,args); + } + jchar CallCharMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallCharMethodA(this,obj,methodID,args); + } + + jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallShortMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jshort CallShortMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallShortMethodV(this,obj,methodID,args); + } + jshort CallShortMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallShortMethodA(this,obj,methodID,args); + } + + jint CallIntMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallIntMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jint CallIntMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallIntMethodV(this,obj,methodID,args); + } + jint CallIntMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallIntMethodA(this,obj,methodID,args); + } + + jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallLongMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jlong CallLongMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallLongMethodV(this,obj,methodID,args); + } + jlong CallLongMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallLongMethodA(this,obj,methodID,args); + } + + jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallFloatMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jfloat CallFloatMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallFloatMethodV(this,obj,methodID,args); + } + jfloat CallFloatMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallFloatMethodA(this,obj,methodID,args); + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallDoubleMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallDoubleMethodV(this,obj,methodID,args); + } + jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallDoubleMethodA(this,obj,methodID,args); + } + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallVoidMethodV(this,obj,methodID,args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, + va_list args) { + functions->CallVoidMethodV(this,obj,methodID,args); + } + void CallVoidMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + functions->CallVoidMethodA(this,obj,methodID,args); + } + + jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + } + jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualObjectMethodA(this,obj,clazz, + methodID,args); + } + + jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + } + jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, + methodID, args); + } + + jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + } + jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualByteMethodA(this,obj,clazz, + methodID,args); + } + + jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + } + jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualCharMethodA(this,obj,clazz, + methodID,args); + } + + jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + } + jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualShortMethodA(this,obj,clazz, + methodID,args); + } + + jint CallNonvirtualIntMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + } + jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualIntMethodA(this,obj,clazz, + methodID,args); + } + + jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + } + jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualLongMethodA(this,obj,clazz, + methodID,args); + } + + jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + } + jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, + jmethodID methodID, + jvalue * args) { + return functions->CallNonvirtualFloatMethodA(this,obj,clazz, + methodID,args); + } + + jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + } + jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, + jmethodID methodID, + jvalue * args) { + return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, + methodID,args); + } + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, + jvalue * args) { + functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); + } + + jfieldID GetFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetFieldID(this,clazz,name,sig); + } + + jobject GetObjectField(jobject obj, jfieldID fieldID) { + return functions->GetObjectField(this,obj,fieldID); + } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) { + return functions->GetBooleanField(this,obj,fieldID); + } + jbyte GetByteField(jobject obj, jfieldID fieldID) { + return functions->GetByteField(this,obj,fieldID); + } + jchar GetCharField(jobject obj, jfieldID fieldID) { + return functions->GetCharField(this,obj,fieldID); + } + jshort GetShortField(jobject obj, jfieldID fieldID) { + return functions->GetShortField(this,obj,fieldID); + } + jint GetIntField(jobject obj, jfieldID fieldID) { + return functions->GetIntField(this,obj,fieldID); + } + jlong GetLongField(jobject obj, jfieldID fieldID) { + return functions->GetLongField(this,obj,fieldID); + } + jfloat GetFloatField(jobject obj, jfieldID fieldID) { + return functions->GetFloatField(this,obj,fieldID); + } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) { + return functions->GetDoubleField(this,obj,fieldID); + } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { + functions->SetObjectField(this,obj,fieldID,val); + } + void SetBooleanField(jobject obj, jfieldID fieldID, + jboolean val) { + functions->SetBooleanField(this,obj,fieldID,val); + } + void SetByteField(jobject obj, jfieldID fieldID, + jbyte val) { + functions->SetByteField(this,obj,fieldID,val); + } + void SetCharField(jobject obj, jfieldID fieldID, + jchar val) { + functions->SetCharField(this,obj,fieldID,val); + } + void SetShortField(jobject obj, jfieldID fieldID, + jshort val) { + functions->SetShortField(this,obj,fieldID,val); + } + void SetIntField(jobject obj, jfieldID fieldID, + jint val) { + functions->SetIntField(this,obj,fieldID,val); + } + void SetLongField(jobject obj, jfieldID fieldID, + jlong val) { + functions->SetLongField(this,obj,fieldID,val); + } + void SetFloatField(jobject obj, jfieldID fieldID, + jfloat val) { + functions->SetFloatField(this,obj,fieldID,val); + } + void SetDoubleField(jobject obj, jfieldID fieldID, + jdouble val) { + functions->SetDoubleField(this,obj,fieldID,val); + } + + jmethodID GetStaticMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticMethodID(this,clazz,name,sig); + } + + jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, + ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->CallStaticObjectMethodV(this,clazz,methodID,args); + } + jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, + jvalue *args) { + return functions->CallStaticObjectMethodA(this,clazz,methodID,args); + } + + jboolean CallStaticBooleanMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jboolean CallStaticBooleanMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + } + jboolean CallStaticBooleanMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); + } + + jbyte CallStaticByteMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallStaticByteMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jbyte CallStaticByteMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticByteMethodV(this,clazz,methodID,args); + } + jbyte CallStaticByteMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticByteMethodA(this,clazz,methodID,args); + } + + jchar CallStaticCharMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallStaticCharMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jchar CallStaticCharMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticCharMethodV(this,clazz,methodID,args); + } + jchar CallStaticCharMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticCharMethodA(this,clazz,methodID,args); + } + + jshort CallStaticShortMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallStaticShortMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jshort CallStaticShortMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticShortMethodV(this,clazz,methodID,args); + } + jshort CallStaticShortMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticShortMethodA(this,clazz,methodID,args); + } + + jint CallStaticIntMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallStaticIntMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jint CallStaticIntMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticIntMethodV(this,clazz,methodID,args); + } + jint CallStaticIntMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticIntMethodA(this,clazz,methodID,args); + } + + jlong CallStaticLongMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallStaticLongMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jlong CallStaticLongMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticLongMethodV(this,clazz,methodID,args); + } + jlong CallStaticLongMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticLongMethodA(this,clazz,methodID,args); + } + + jfloat CallStaticFloatMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jfloat CallStaticFloatMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticFloatMethodV(this,clazz,methodID,args); + } + jfloat CallStaticFloatMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticFloatMethodA(this,clazz,methodID,args); + } + + jdouble CallStaticDoubleMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jdouble CallStaticDoubleMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + } + jdouble CallStaticDoubleMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); + } + + void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallStaticVoidMethodV(this,cls,methodID,args); + va_end(args); + } + void CallStaticVoidMethodV(jclass cls, jmethodID methodID, + va_list args) { + functions->CallStaticVoidMethodV(this,cls,methodID,args); + } + void CallStaticVoidMethodA(jclass cls, jmethodID methodID, + jvalue * args) { + functions->CallStaticVoidMethodA(this,cls,methodID,args); + } + + jfieldID GetStaticFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticFieldID(this,clazz,name,sig); + } + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticObjectField(this,clazz,fieldID); + } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticBooleanField(this,clazz,fieldID); + } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticByteField(this,clazz,fieldID); + } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticCharField(this,clazz,fieldID); + } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticShortField(this,clazz,fieldID); + } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticIntField(this,clazz,fieldID); + } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticLongField(this,clazz,fieldID); + } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticFloatField(this,clazz,fieldID); + } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticDoubleField(this,clazz,fieldID); + } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, + jobject value) { + functions->SetStaticObjectField(this,clazz,fieldID,value); + } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, + jboolean value) { + functions->SetStaticBooleanField(this,clazz,fieldID,value); + } + void SetStaticByteField(jclass clazz, jfieldID fieldID, + jbyte value) { + functions->SetStaticByteField(this,clazz,fieldID,value); + } + void SetStaticCharField(jclass clazz, jfieldID fieldID, + jchar value) { + functions->SetStaticCharField(this,clazz,fieldID,value); + } + void SetStaticShortField(jclass clazz, jfieldID fieldID, + jshort value) { + functions->SetStaticShortField(this,clazz,fieldID,value); + } + void SetStaticIntField(jclass clazz, jfieldID fieldID, + jint value) { + functions->SetStaticIntField(this,clazz,fieldID,value); + } + void SetStaticLongField(jclass clazz, jfieldID fieldID, + jlong value) { + functions->SetStaticLongField(this,clazz,fieldID,value); + } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, + jfloat value) { + functions->SetStaticFloatField(this,clazz,fieldID,value); + } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, + jdouble value) { + functions->SetStaticDoubleField(this,clazz,fieldID,value); + } + + jstring NewString(const jchar *unicode, jsize len) { + return functions->NewString(this,unicode,len); + } + jsize GetStringLength(jstring str) { + return functions->GetStringLength(this,str); + } + const jchar *GetStringChars(jstring str, jboolean *isCopy) { + return functions->GetStringChars(this,str,isCopy); + } + void ReleaseStringChars(jstring str, const jchar *chars) { + functions->ReleaseStringChars(this,str,chars); + } + + jstring NewStringUTF(const char *utf) { + return functions->NewStringUTF(this,utf); + } + jsize GetStringUTFLength(jstring str) { + return functions->GetStringUTFLength(this,str); + } + const char* GetStringUTFChars(jstring str, jboolean *isCopy) { + return functions->GetStringUTFChars(this,str,isCopy); + } + void ReleaseStringUTFChars(jstring str, const char* chars) { + functions->ReleaseStringUTFChars(this,str,chars); + } + + jsize GetArrayLength(jarray array) { + return functions->GetArrayLength(this,array); + } + + jobjectArray NewObjectArray(jsize len, jclass clazz, + jobject init) { + return functions->NewObjectArray(this,len,clazz,init); + } + jobject GetObjectArrayElement(jobjectArray array, jsize index) { + return functions->GetObjectArrayElement(this,array,index); + } + void SetObjectArrayElement(jobjectArray array, jsize index, + jobject val) { + functions->SetObjectArrayElement(this,array,index,val); + } + + jbooleanArray NewBooleanArray(jsize len) { + return functions->NewBooleanArray(this,len); + } + jbyteArray NewByteArray(jsize len) { + return functions->NewByteArray(this,len); + } + jcharArray NewCharArray(jsize len) { + return functions->NewCharArray(this,len); + } + jshortArray NewShortArray(jsize len) { + return functions->NewShortArray(this,len); + } + jintArray NewIntArray(jsize len) { + return functions->NewIntArray(this,len); + } + jlongArray NewLongArray(jsize len) { + return functions->NewLongArray(this,len); + } + jfloatArray NewFloatArray(jsize len) { + return functions->NewFloatArray(this,len); + } + jdoubleArray NewDoubleArray(jsize len) { + return functions->NewDoubleArray(this,len); + } + + jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { + return functions->GetBooleanArrayElements(this,array,isCopy); + } + jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + return functions->GetByteArrayElements(this,array,isCopy); + } + jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { + return functions->GetCharArrayElements(this,array,isCopy); + } + jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { + return functions->GetShortArrayElements(this,array,isCopy); + } + jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { + return functions->GetIntArrayElements(this,array,isCopy); + } + jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { + return functions->GetLongArrayElements(this,array,isCopy); + } + jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { + return functions->GetFloatArrayElements(this,array,isCopy); + } + jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { + return functions->GetDoubleArrayElements(this,array,isCopy); + } + + void ReleaseBooleanArrayElements(jbooleanArray array, + jboolean *elems, + jint mode) { + functions->ReleaseBooleanArrayElements(this,array,elems,mode); + } + void ReleaseByteArrayElements(jbyteArray array, + jbyte *elems, + jint mode) { + functions->ReleaseByteArrayElements(this,array,elems,mode); + } + void ReleaseCharArrayElements(jcharArray array, + jchar *elems, + jint mode) { + functions->ReleaseCharArrayElements(this,array,elems,mode); + } + void ReleaseShortArrayElements(jshortArray array, + jshort *elems, + jint mode) { + functions->ReleaseShortArrayElements(this,array,elems,mode); + } + void ReleaseIntArrayElements(jintArray array, + jint *elems, + jint mode) { + functions->ReleaseIntArrayElements(this,array,elems,mode); + } + void ReleaseLongArrayElements(jlongArray array, + jlong *elems, + jint mode) { + functions->ReleaseLongArrayElements(this,array,elems,mode); + } + void ReleaseFloatArrayElements(jfloatArray array, + jfloat *elems, + jint mode) { + functions->ReleaseFloatArrayElements(this,array,elems,mode); + } + void ReleaseDoubleArrayElements(jdoubleArray array, + jdouble *elems, + jint mode) { + functions->ReleaseDoubleArrayElements(this,array,elems,mode); + } + + void GetBooleanArrayRegion(jbooleanArray array, + jsize start, jsize len, jboolean *buf) { + functions->GetBooleanArrayRegion(this,array,start,len,buf); + } + void GetByteArrayRegion(jbyteArray array, + jsize start, jsize len, jbyte *buf) { + functions->GetByteArrayRegion(this,array,start,len,buf); + } + void GetCharArrayRegion(jcharArray array, + jsize start, jsize len, jchar *buf) { + functions->GetCharArrayRegion(this,array,start,len,buf); + } + void GetShortArrayRegion(jshortArray array, + jsize start, jsize len, jshort *buf) { + functions->GetShortArrayRegion(this,array,start,len,buf); + } + void GetIntArrayRegion(jintArray array, + jsize start, jsize len, jint *buf) { + functions->GetIntArrayRegion(this,array,start,len,buf); + } + void GetLongArrayRegion(jlongArray array, + jsize start, jsize len, jlong *buf) { + functions->GetLongArrayRegion(this,array,start,len,buf); + } + void GetFloatArrayRegion(jfloatArray array, + jsize start, jsize len, jfloat *buf) { + functions->GetFloatArrayRegion(this,array,start,len,buf); + } + void GetDoubleArrayRegion(jdoubleArray array, + jsize start, jsize len, jdouble *buf) { + functions->GetDoubleArrayRegion(this,array,start,len,buf); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + jboolean *buf) { + functions->SetBooleanArrayRegion(this,array,start,len,buf); + } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + jbyte *buf) { + functions->SetByteArrayRegion(this,array,start,len,buf); + } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + jchar *buf) { + functions->SetCharArrayRegion(this,array,start,len,buf); + } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + jshort *buf) { + functions->SetShortArrayRegion(this,array,start,len,buf); + } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + jint *buf) { + functions->SetIntArrayRegion(this,array,start,len,buf); + } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + jlong *buf) { + functions->SetLongArrayRegion(this,array,start,len,buf); + } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + jfloat *buf) { + functions->SetFloatArrayRegion(this,array,start,len,buf); + } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + jdouble *buf) { + functions->SetDoubleArrayRegion(this,array,start,len,buf); + } + + jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, + jint nMethods) { + return functions->RegisterNatives(this,clazz,methods,nMethods); + } + jint UnregisterNatives(jclass clazz) { + return functions->UnregisterNatives(this,clazz); + } + + jint MonitorEnter(jobject obj) { + return functions->MonitorEnter(this,obj); + } + jint MonitorExit(jobject obj) { + return functions->MonitorExit(this,obj); + } + + jint GetJavaVM(JavaVM **vm) { + return functions->GetJavaVM(this,vm); + } + + void GetStringRegion(jstring s, jsize off, jsize len, jchar* d) { + functions->GetStringRegion(this, s, off, len, d); + } + void GetStringUTFRegion(jstring s, jsize off, jsize len, char* d) { + functions->GetStringUTFRegion(this, s, off, len, d); + } + + void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy) { + return functions->GetPrimitiveArrayCritical(this, array, isCopy); + } + + void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode) { + functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); + } + + const jchar* GetStringCritical(jstring s, jboolean* isCopy) { + return functions->GetStringCritical(this, s, isCopy); + } + void ReleaseStringCritical(jstring s, const jchar* cstr) { + functions->ReleaseStringCritical(this, s, cstr); + } + + jweak NewWeakGlobalRef(jobject obj) { + return functions->NewWeakGlobalRef(this, obj); + } + + void DeleteWeakGlobalRef(jweak obj) { + functions->DeleteWeakGlobalRef(this, obj); + } + + jboolean ExceptionCheck() { + return functions->ExceptionCheck(this); + } + + jobject NewDirectByteBuffer(void *address, jlong capacity) { + return functions->NewDirectByteBuffer(this, address, capacity); + } + void *GetDirectBufferAddress(jobject buf) { + return functions->GetDirectBufferAddress(this, buf); + } + jlong GetDirectBufferCapacity(jobject buf) { + return functions->GetDirectBufferCapacity(this, buf); + } +#endif + +}; + +/** + * Structure which describes one Java VM invocation argument + * + * See specification + * for details. + */ +typedef struct JavaVMOption { + char *optionString; + void *extraInfo; +} JavaVMOption; + +/** + * Structure which describes one Java VM invocation arguments for JNI + * interface version 1.2 and greater + * + * See specification + * for details. + */ +typedef struct JavaVMInitArgs { + jint version; + jint nOptions; + JavaVMOption *options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +/** + * Structure which describes arguments for attaching a native thread to a Java VM + * + * See specification + * for details. + */ +typedef struct JavaVMAttachArgs { + jint version; + char *name; + jobject group; +} JavaVMAttachArgs; + +/** + * JNI Invocation Interface table for use in C sources + * + * See + * specification for details + */ +struct JNIInvokeInterface_ { + void* reserved0; + void* reserved1; + void* reserved2; + + jint (JNICALL *DestroyJavaVM)(JavaVM*); + + jint (JNICALL *AttachCurrentThread)(JavaVM*, void** penv, void* args); + jint (JNICALL *DetachCurrentThread)(JavaVM*); + + jint (JNICALL *GetEnv)(JavaVM*, void** penv, jint ver); + + jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM*, void** penv, void* args); +}; + +/** + * JNI Invocation Interface table for use in C++ sources + * + * See + * specification for details + */ +struct JavaVM_External { + const struct JNIInvokeInterface_* functions; + +#ifdef __cplusplus + jint DestroyJavaVM() { + return functions->DestroyJavaVM(this); + } + + jint AttachCurrentThread(void** penv, void* args) { + return functions->AttachCurrentThread(this, penv, args); + } + + jint DetachCurrentThread() { + return functions->DetachCurrentThread(this); + } + + jint GetEnv(void** penv, jint ver) { + return functions->GetEnv(this, penv, ver); + } + + jint AttachCurrentThreadAsDaemon(void** penv, void* args) { + return functions->AttachCurrentThreadAsDaemon(this, penv, args); + } + +#endif +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @def _JNI_EXPORT_ + * Function attribute used when building VM from sources + */ +#ifdef BUILDING_VM +#define _JNI_EXPORT_ +#else +#define _JNI_EXPORT_ JNIIMPORT +#endif + +/** + * Function to get the default VM arguments + * + * See specification + * for details. + */ +_JNI_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void * vm_args); + +/** + * Function to get an array of already created Java VMs in the current + * process + * + * See specification + * for details. + */ +_JNI_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM ** vmBuf, + jsize bufLen, + jsize * nVMs); + +/** + * Creates Java VM in the current process + * + * See specification + * for details. + */ +_JNI_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM ** p_vm, JNIEnv ** p_env, + void * vm_args); + +#ifdef __cplusplus +} +#endif + + +#endif /* _JNI_H_ */ diff --git a/platform/o.n.bootstrap/launcher/windows/include/jni_types.h b/platform/o.n.bootstrap/launcher/windows/include/jni_types.h new file mode 100644 index 000000000000..a809ebba8f33 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/include/jni_types.h @@ -0,0 +1,451 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _JNI_TYPES_H_ +#define _JNI_TYPES_H_ + +/** + * @file + * Types used in JNI and OPEN interfaces. + * + * For the most part JNI types are defined by Sun specification on + * Java Native Interface (JNI). See specification + * for details. + */ + +/* The following documentation is both for windows and linux, so it + * resides outside of ifdef-endif block */ +/** + * @def JNIEXPORT + * Function attribute to make native JNI function exportable + */ +/** + * @def JNIIMPORT + * Function attribute used when building VM from sources + */ +/** + * @def JNICALL + * Function attribute to specify calling conventions that should be + * used for native JNI functions + */ +/** + * @typedef jlong + * Signed 64-bit long type equivalent to Java "long" type + */ +#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32) + +#define JNIEXPORT __declspec(dllexport) +#define JNIIMPORT __declspec(dllimport) +#define JNICALL __stdcall + +typedef signed __int64 jlong; + +#else + +#define JNIEXPORT +#define JNIIMPORT +#define JNICALL + +typedef signed long long jlong; + +#endif + +/* + * Primitive types + */ +/** + * Unsigned 8-bit primitive boolean type equivalent to Java "boolean" + * type + * + * See specification + * for details. + */ +typedef unsigned char jboolean; +/** + * Signed 8-bit primitive byte type equivalent to Java "byte" type + * + * See specification + * for details. + */ +typedef signed char jbyte; +/** + * Unsigned 16-bit primitive char type equivalent to Java "char" type + * + * See specification + * for details. + */ +typedef unsigned short jchar; +/** + * Signed 16-bit primitive short type equivalent to Java "short" type + * + * See specification + * for details. + */ +typedef signed short jshort; +/** + * Signed 32-bit primitive integer type equivalent to Java "int" type + * + * See specification + * for details. + */ +typedef signed int jint; +/** + * Signed 32-bit primitive floating point type equivalent to Java + * "float" type + * + * See specification + * for details. + */ +typedef float jfloat; +/** + * Signed 64-bit primitive floating point type equivalent to Java + * "double" type + * + * See specification + * for details. + */ +typedef double jdouble; +/** + * Signed 32-bit primitive integer type used to describe sizes + * + * See specification + * for details. + */ +typedef jint jsize; + +/* + * Java types + */ +struct _jobject; +/** + * Reference type which describes a general Java object in native + * function + * + * See specification + * for details. + */ +typedef struct _jobject* jobject; +/** + * Reference type which describes a java.lang.Class instance object in + * native function + * + * See specification + * for details. + */ +typedef jobject jclass; +/** + * Reference type which describes a java.lang.String instance object + * in native function + * + * See specification + * for details. + */ +typedef jobject jstring; +/** + * Reference type which describes a generic array instance object in + * native function + * + * See specification + * for details. + */ +typedef jobject jarray; +/** + * Reference type which describes an array of java.lang.Object + * instances in native function + * + * See specification + * for details. + */ + typedef jarray jobjectArray; +/** + * Reference type which describes an array of booleans in native + * function + * + * See specification + * for details. + */ + typedef jarray jbooleanArray; +/** + * Reference type which describes an array of bytes type in native + * function + * + * See specification + * for details. + */ + typedef jarray jbyteArray; +/** + * Reference type which describes an array of chars type in native + * function + * + * See specification + * for details. + */ + typedef jarray jcharArray; +/** + * Reference type which describes an array of shorts type in native + * function + * + * See specification + * for details. + */ + typedef jarray jshortArray; +/** + * Reference type which describes an array of ints type in native + * function + * + * See specification + * for details. + */ + typedef jarray jintArray; +/** + * Reference type which describes an array of longs type in native + * function + * + * See specification + * for details. + */ + typedef jarray jlongArray; +/** + * Reference type which describes an array of floats type in native + * function + * + * See specification + * for details. + */ + typedef jarray jfloatArray; +/** + * Reference type which describes an array of doubles type in native + * function + * + * See specification + * for details. + */ + typedef jarray jdoubleArray; +/** + * Reference type which describes a java.lang.Throwable instance + * object in native function + * + * See specification + * for details. + */ +typedef jobject jthrowable; +/** + * Reference type which describes a weak reference to a general object + * + * This type is the same as #jobject but the reference held in it + * is weak, so if the referred object is weakly reacheable, it may be + * garbage collected to VM. + */ +typedef jobject jweak; + +/** + * This union used to pass arguments to native functions when Call<type>MethodA + * and CallStatic<type>MethodA + * functions are used + * + * It consists of all possible primitive Java types plus #jobject, so + * it is possible to pass any kind of argument type through it. + */ +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +/** + * Type which describes an identfier of a field inside of class + * + * This type together with a #jclass reference uniquily identifies a + * field inside of the class described by #jclass. + */ +typedef struct _jfieldID* jfieldID; + +/** + * Type which describes an identfier of a method inside of class + * + * This type together with a #jclass reference uniquily identifies a + * method inside of the class described by #jclass. + */ +typedef struct _jmethodID* jmethodID; + +/* + * Constants + */ + +/* + * Boolean constants + */ +/** + * Constant which defines boolean truth in native Java functions. It + * is equivalent to Java constant "true" + */ +#define JNI_FALSE 0 +/** + * Constant which defines boolean false in native Java functions. It + * is equivalent to Java constant "false" + */ +#define JNI_TRUE 1 + +/* + * Return values + */ +/** + * Constant which describes success when returned by JNI API functions + */ +#define JNI_OK 0 +/** + * Constant which describes an error when returned by JNI API + * functions + */ +#define JNI_ERR (-1) +/** + * Constant which describes a deatached thread condition when returned + * by JNI API functions + */ +#define JNI_EDETACHED (-2) +/** + * Constant which describes wrong JNI interface verions when returned + * by JNI API functions + */ +#define JNI_EVERSION (-3) +/** + * Constant which describes out of memory condition when returned by + * JNI API functions + */ +#define JNI_ENOMEM (-4) +/** + * Constant which means that a limited resource already exists when + * returned by JNI API functions + */ +#define JNI_EEXIST (-5) +/** + * Constant which means that an illegal argument value was passed to a + * JNI function + */ +#define JNI_EINVAL (-6) + +/* + * Release modes for working with arrays. + */ +/** + * Constant which means that an array region should be committed into + * memory. Used in ReleaseArrayElements functions + */ +#define JNI_COMMIT 1 +/** + * Constant which means that an array region should be discarded. Used + * in ReleaseArrayElements functions + */ +#define JNI_ABORT 2 + +/* + * Used as a generic pointer to a function. + */ +/** + * Structure which describes a generic pointer to a native + * function. Used in RegisterNatives + * function. + */ +typedef struct { + char *name; + char *signature; + void *fnPtr; +} JNINativeMethod; + +/* + * JNI Native Method Interface + */ +struct JNINativeInterface_; +struct JNIEnv_External; + +#ifdef __cplusplus +/** + * JNI API interface table type for usage in C++ + * + * See specification + * for details. */ +typedef JNIEnv_External JNIEnv; +#else +/** + * JNI API interface table type for usage in C + * + * See specification + * for details. */ +typedef const struct JNINativeInterface_ *JNIEnv; +#endif + +/* + * JNI Invocation Interface + */ +struct JNIInvokeInterface_; +struct JavaVM_External; + +#ifdef __cplusplus +/** + * Java VM interface table type for usage in C++ + * + * See specification + * for details + */ +typedef JavaVM_External JavaVM; +#else +/** + * Java VM interface table type for usage in C + * + * See specification + * for details + */ +typedef const struct JNIInvokeInterface_ *JavaVM; +#endif + +#endif /* _JNI_TYPES_H_ */ diff --git a/platform/o.n.bootstrap/launcher/windows/jvmlauncher.cpp b/platform/o.n.bootstrap/launcher/windows/jvmlauncher.cpp new file mode 100644 index 000000000000..74bf1cc91932 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/jvmlauncher.cpp @@ -0,0 +1,454 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#include "jvmlauncher.h" +#include + +using namespace std; + +const char *JvmLauncher::JDK_KEY = "Software\\JavaSoft\\Java Development Kit"; +const char *JvmLauncher::JRE_KEY = "Software\\JavaSoft\\Java Runtime Environment"; +const char *JvmLauncher::JDK_POST9_KEY = "Software\\JavaSoft\\JDK"; +const char *JvmLauncher::JRE_POST9_KEY = "Software\\JavaSoft\\JRE"; +const char *JvmLauncher::CUR_VERSION_NAME = "CurrentVersion"; +const char *JvmLauncher::JAVA_HOME_NAME = "JavaHome"; +const char *JvmLauncher::JAVA_BIN_DIR = "\\bin"; +const char *JvmLauncher::JAVA_EXE_FILE = "\\bin\\java.exe"; +const char *JvmLauncher::JAVAW_EXE_FILE = "\\bin\\javaw.exe"; +const char *JvmLauncher::JAVA_CLIENT_DLL_FILE = "\\bin\\client\\jvm.dll"; +const char *JvmLauncher::JAVA_SERVER_DLL_FILE = "\\bin\\server\\jvm.dll"; +const char *JvmLauncher::JAVA_JRE_PREFIX = "\\jre"; +const char *JvmLauncher::JNI_CREATEVM_FUNC = "JNI_CreateJavaVM"; + +extern void exitHook(int status); + +JvmLauncher::JvmLauncher() + : suppressConsole(false) { +} + +JvmLauncher::JvmLauncher(const JvmLauncher& orig) { +} + +JvmLauncher::~JvmLauncher() { +} + +bool JvmLauncher::checkJava(const char *path, const char *prefix) { + assert(path); + assert(prefix); + logMsg("checkJava(%s)", path); + javaPath = path; + if (*javaPath.rbegin() == '\\') { + javaPath.erase(javaPath.length() - 1, 1); + } + javaExePath = javaPath + prefix + JAVA_EXE_FILE; + javawExePath = javaPath + prefix + JAVAW_EXE_FILE; + javaClientDllPath = javaPath + prefix + JAVA_CLIENT_DLL_FILE; + javaServerDllPath = javaPath + prefix + JAVA_SERVER_DLL_FILE; + if (!fileExists(javaClientDllPath.c_str())) { + javaClientDllPath = ""; + } + if (!fileExists(javaServerDllPath.c_str())) { + javaServerDllPath = ""; + } + javaBinPath = javaPath + prefix + JAVA_BIN_DIR; + if (fileExists(javaExePath.c_str()) || !javaClientDllPath.empty() || !javaServerDllPath.empty()) { + if (!fileExists(javawExePath.c_str())) { + logMsg("javaw.exe not exists, forcing java.exe"); + javawExePath = javaExePath; + } + return true; + } + + javaPath.clear(); + javaBinPath.clear(); + javaExePath.clear(); + javawExePath.clear(); + javaClientDllPath.clear(); + javaServerDllPath.clear(); + return false; +} + +bool JvmLauncher::initialize(const char *javaPathOrMinVersion) { + logMsg("JvmLauncher::initialize()\n\tjavaPathOrMinVersion: %s", javaPathOrMinVersion); + assert(javaPathOrMinVersion); + if (isVersionString(javaPathOrMinVersion)) { + return findJava(javaPathOrMinVersion); + } else { + return (checkJava(javaPathOrMinVersion, JAVA_JRE_PREFIX) || checkJava(javaPathOrMinVersion, "")); + } +} + +bool JvmLauncher::getJavaPath(string &path) { + logMsg("JvmLauncher::getJavaPath()"); + path = javaPath; + return !javaPath.empty(); +} + +bool JvmLauncher::start(const char *mainClassName, const list &args, const list &options, bool &separateProcess, DWORD *retCode) { + assert(mainClassName); + logMsg("JvmLauncher::start()\n\tmainClassName: %s\n\tseparateProcess: %s", + mainClassName, separateProcess ? "true" : "false"); + logMsg(" args:"); + for (list::const_iterator it = args.begin(); it != args.end(); ++it) { + logMsg("\t%s", it->c_str()); + } + logMsg(" options:"); + for (list::const_iterator it = options.begin(); it != options.end(); ++it) { + logMsg("\t%s", it->c_str()); + } + + if (!javaExePath.empty() && javaClientDllPath.empty() && javaServerDllPath.empty()) { + logMsg("Found only java.exe at %s. No DLLs. Falling back to java.exe\n", javaExePath.c_str()); + separateProcess = true; + } else { + if (javaExePath.empty() || (javaClientDllPath.empty() && javaServerDllPath.empty())) { + if (!initialize("")) { + return false; + } + } + } + + if (!separateProcess) { + // both client/server found, check option which should be used + if (!javaClientDllPath.empty() && !javaServerDllPath.empty()) { + javaDllPath = findClientOption(options) ? javaClientDllPath : javaServerDllPath; + } else { + javaDllPath = javaClientDllPath.empty() ? javaServerDllPath : javaClientDllPath; + } + + // it is necessary to absolutize dll path because current dir has to be + // temporarily changed for dll loading + char absoluteJavaDllPath[MAX_PATH] = ""; + strncpy(absoluteJavaDllPath, javaDllPath.c_str(), MAX_PATH); + normalizePath(absoluteJavaDllPath, MAX_PATH); + javaDllPath = absoluteJavaDllPath; + + logMsg("Java DLL path: %s", javaDllPath.c_str()); + if (!canLoadJavaDll()) { + logMsg("Falling back to running Java in a separate process; DLL cannot be loaded (64-bit DLL?)."); + separateProcess = true; + } + } + + return separateProcess ? startOutProcJvm(mainClassName, args, options, retCode) + : startInProcJvm(mainClassName, args, options); +} + +bool JvmLauncher::findClientOption(const list &options) { + for (list::const_iterator it = options.begin(); it != options.end(); ++it) { + if (*it == "-client") { + return true; + } + } + return false; +} + +bool JvmLauncher::canLoadJavaDll() { + // be prepared for stupid placement of msvcr71.dll in java installation + // (in java 1.6/1.7 jvm.dll is dynamically linked to msvcr71.dll which si placed + // in bin directory) + PrepareDllPath prepare(javaBinPath.c_str()); + HMODULE hDll = LoadLibrary(javaDllPath.c_str()); + if (hDll) { + FreeLibrary(hDll); + return true; + } + logErr(true, false, "Cannot load %s.", javaDllPath.c_str()); + return false; +} + +bool JvmLauncher::isVersionString(const char *str) { + char *end = 0; + strtod(str, &end); + return *end == '\0'; +} + +bool JvmLauncher::startInProcJvm(const char *mainClassName, const std::list &args, const std::list &options) { + class Jvm { + public: + + Jvm(JvmLauncher *jvmLauncher) + : hDll(0) + , hSplash(0) + , jvm(0) + , env(0) + , jvmOptions(0) + , jvmLauncher(jvmLauncher) + { + } + + ~Jvm() { + if (env && env->ExceptionOccurred()) { + env->ExceptionDescribe(); + } + + if (jvm) { + logMsg("Destroying JVM"); + jvm->DestroyJavaVM(); + } + + if (jvmOptions) { + delete[] jvmOptions; + } + + if (hDll) { + FreeLibrary(hDll); + } + if (hSplash) { + FreeLibrary(hSplash); + } + } + + bool init(const list &options) { + logMsg("JvmLauncher::Jvm::init()"); + logMsg("LoadLibrary(\"%s\")", jvmLauncher->javaDllPath.c_str()); + { + PrepareDllPath prepare(jvmLauncher->javaBinPath.c_str()); + hDll = LoadLibrary(jvmLauncher->javaDllPath.c_str()); + if (!hDll) { + logErr(true, true, "Cannot load %s.", jvmLauncher->javaDllPath.c_str()); + return false; + } + + string pref = jvmLauncher->javaBinPath; + pref += "\\splashscreen.dll"; + const string splash = pref; + logMsg("Trying to load %s", splash.c_str()); + hSplash = LoadLibrary(splash.c_str()); + logMsg("Splash loaded as %d", hSplash); + } + + CreateJavaVM createJavaVM = (CreateJavaVM) GetProcAddress(hDll, JNI_CREATEVM_FUNC); + if (!createJavaVM) { + logErr(true, true, "GetProcAddress for %s failed.", JNI_CREATEVM_FUNC); + return false; + } + + logMsg("JVM options:"); + jvmOptions = new JavaVMOption[options.size() + 1]; + int i = 0; + for (list::const_iterator it = options.begin(); it != options.end(); ++it, ++i) { + const string &option = *it; + logMsg("\t%s", option.c_str()); + if (option.find("-splash:") == 0 && hSplash > 0) { + const string splash = option.substr(8); + logMsg("splash at %s", splash.c_str()); + + SplashInit splashInit = (SplashInit)GetProcAddress(hSplash, "SplashInit"); + SplashLoadFile splashLoadFile = (SplashLoadFile)GetProcAddress(hSplash, "SplashLoadFile"); + + logMsg("splash init %d and load %d", splashInit, splashLoadFile); + if (splashInit && splashLoadFile) { + splashInit(); + splashLoadFile(splash.c_str()); + } + } + jvmOptions[i].optionString = (char *) option.c_str(); + jvmOptions[i].extraInfo = 0; + } + JavaVMInitArgs jvmArgs; + jvmOptions[options.size()].optionString = (char *) "exit"; + jvmOptions[options.size()].extraInfo = (void *) &exitHook; + + jvmArgs.options = jvmOptions; + jvmArgs.nOptions = options.size() + 1; + jvmArgs.version = JNI_VERSION_1_4; + jvmArgs.ignoreUnrecognized = JNI_TRUE; + + logMsg("Creating JVM..."); + if (createJavaVM(&jvm, &env, &jvmArgs) < 0) { + logErr(false, true, "JVM creation failed"); + return false; + } + logMsg("JVM created."); + return true; + } + typedef jint (CALLBACK *CreateJavaVM)(JavaVM **jvm, JNIEnv **env, void *args); + typedef void (CALLBACK *SplashInit)(); + typedef int (CALLBACK *SplashLoadFile)(const char* file); + + HMODULE hDll; + HMODULE hSplash; + JavaVM *jvm; + JNIEnv *env; + JavaVMOption *jvmOptions; + JvmLauncher *jvmLauncher; + }; + + Jvm jvm(this); + if (!jvm.init(options)) { + return false; + } + + jclass mainClass = jvm.env->FindClass(mainClassName); + if (!mainClass) { + logErr(false, true, "Cannot find class %s.", mainClassName); + return false; + } + + jmethodID mainMethod = jvm.env->GetStaticMethodID(mainClass, "main", "([Ljava/lang/String;)V"); + if (!mainMethod) { + logErr(false, true, "Cannot get main method."); + return false; + } + + jclass jclassString = jvm.env->FindClass("java/lang/String"); + if (!jclassString) { + logErr(false, true, "Cannot find java/lang/String class"); + return false; + } + + jstring jstringArg = jvm.env->NewStringUTF(""); + if (!jstringArg) { + logErr(false, true, "NewStringUTF() failed"); + return false; + } + + jobjectArray mainArgs = jvm.env->NewObjectArray(args.size(), jclassString, jstringArg); + if (!mainArgs) { + logErr(false, true, "NewObjectArray() failed"); + return false; + } + int i = 0; + for (list::const_iterator it = args.begin(); it != args.end(); ++it, ++i) { + const string &arg = *it; + const int len = 32*1024; + char utf8[len] = ""; + if (convertAnsiToUtf8(arg.c_str(), utf8, len)) + logMsg("Conversion to UTF8 failed"); + jstring jstringArg = jvm.env->NewStringUTF(utf8); + if (!jstringArg) { + logErr(false, true, "NewStringUTF() failed"); + return false; + } + jvm.env->SetObjectArrayElement(mainArgs, i, jstringArg); + } + + jvm.env->CallStaticVoidMethod(mainClass, mainMethod, mainArgs); + return true; +} + + +bool JvmLauncher::startOutProcJvm(const char *mainClassName, const std::list &args, const std::list &options, DWORD *retCode) { + string cmdLine = '\"' + (suppressConsole ? javawExePath : javaExePath) + '\"'; + cmdLine.reserve(32*1024); + for (list::const_iterator it = options.begin(); it != options.end(); ++it) { + cmdLine += " \""; + cmdLine += *it; + cmdLine += "\""; + } + + // mainClass and args + cmdLine += ' '; + cmdLine += mainClassName; + for (list::const_iterator it = args.begin(); it != args.end(); ++it) { + if (javaClientDllPath.empty() && *it == "-client") { + logMsg("Removing -client option, client java dll not found."); + // remove client parameter, no client java found + continue; + } + cmdLine += " \""; + cmdLine += *it; + cmdLine += "\""; + } + + logMsg("Command line:\n%s", cmdLine.c_str()); + if (cmdLine.size() >= 32*1024) { + logErr(false, true, "Command line is too long. Length: %u. Maximum length: %u.", cmdLine.c_str(), 32*1024); + return false; + } + + STARTUPINFO si = {0}; + si.cb = sizeof (STARTUPINFO); + PROCESS_INFORMATION pi = {0}; + + char cmdLineStr[32*1024] = ""; + strcpy(cmdLineStr, cmdLine.c_str()); + if (!CreateProcess(NULL, cmdLineStr, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { + logErr(true, true, "Failed to create process"); + return false; + } + + disableFolderVirtualization(pi.hProcess); + ResumeThread(pi.hThread); + WaitForSingleObject(pi.hProcess, INFINITE); + if (retCode) { + GetExitCodeProcess(pi.hProcess, retCode); + } + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + return true; +} + +bool JvmLauncher::findJava(const char *minJavaVersion) { + // scan for registry for jdk/jre version 9 + if (findJava(JDK_POST9_KEY, "", minJavaVersion)) { + return true; + } + if (findJava(JRE_POST9_KEY, "", minJavaVersion)) { + return true; + } + if (findJava(JDK_KEY, JAVA_JRE_PREFIX, minJavaVersion)) { + return true; + } + if (findJava(JRE_KEY, "", minJavaVersion)) { + return true; + } + javaPath = ""; + javaExePath = ""; + javaClientDllPath = ""; + javaServerDllPath = ""; + javaBinPath = ""; + return false; +} + +bool JvmLauncher::findJava(const char *javaKey, const char *prefix, const char *minJavaVersion) { + logMsg("JvmLauncher::findJava()\n\tjavaKey: %s\n\tprefix: %s\n\tminJavaVersion: %s", javaKey, prefix, minJavaVersion); + string value; + bool result = false; + if (getStringFromRegistry(HKEY_LOCAL_MACHINE, javaKey, CUR_VERSION_NAME, value)) { + if (value >= minJavaVersion) { + string path; + if (getStringFromRegistry(HKEY_LOCAL_MACHINE, (string(javaKey) + "\\" + value).c_str(), JAVA_HOME_NAME, path)) { + if (*path.rbegin() == '\\') { + path.erase(path.length() - 1, 1); + } + result = checkJava(path.c_str(), prefix); + } + } + } + if(!result && isWow64()) { + if (getStringFromRegistry64bit(HKEY_LOCAL_MACHINE, javaKey, CUR_VERSION_NAME, value)) { + if (value >= minJavaVersion) { + string path; + if (getStringFromRegistry64bit(HKEY_LOCAL_MACHINE, (string(javaKey) + "\\" + value).c_str(), JAVA_HOME_NAME, path)) { + if (*path.rbegin() == '\\') { + path.erase(path.length() - 1, 1); + } + result = checkJava(path.c_str(), prefix); + } + } + } + } + // probably also need to check 32bit registry when launcher becomes 64-bit but is not the case now. + return result; +} diff --git a/platform/o.n.bootstrap/launcher/windows/jvmlauncher.h b/platform/o.n.bootstrap/launcher/windows/jvmlauncher.h new file mode 100644 index 000000000000..01f4e3448c97 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/jvmlauncher.h @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#ifndef _JVMLAUNCHER_H +#define _JVMLAUNCHER_H + +#include +#include +#include +#include "jni.h" +#include "utilsfuncs.h" + +class JvmLauncher { + static const int MAX_ARGS_LEN = 32*1024; + + static const char *JDK_KEY; + static const char *JRE_KEY; + // registry key change starting with version 9 + static const char *JDK_POST9_KEY; + static const char *JRE_POST9_KEY; + static const char *CUR_VERSION_NAME; + static const char *JAVA_HOME_NAME; + static const char *JAVA_BIN_DIR; + static const char *JAVA_EXE_FILE; + static const char *JAVAW_EXE_FILE; + static const char *JAVA_CLIENT_DLL_FILE; + static const char *JAVA_SERVER_DLL_FILE; + static const char *JAVA_JRE_PREFIX; + static const char *JNI_CREATEVM_FUNC; + +public: + JvmLauncher(); + virtual ~JvmLauncher(); + + bool initialize(const char *javaPathOrMinVersion); + bool getJavaPath(std::string &path); + bool start(const char *mainClassName, const std::list &args, const std::list &options, bool &separateProcess, DWORD *retCode); + + void setSuppressConsole(bool val) { + suppressConsole = val; + } + +private: + JvmLauncher(const JvmLauncher& orig); + + bool checkJava(const char *javaPath, const char *prefix); + bool findJava(const char *minJavaVersion); + bool findJava(const char *javaKey, const char *prefix, const char *minJavaVersion); + bool startOutProcJvm(const char *mainClassName, const std::list &args, const std::list &options, DWORD *retCode); + bool startInProcJvm(const char *mainClassName, const std::list &args, const std::list &options); + bool isVersionString(const char *str); + bool canLoadJavaDll(); + bool findClientOption(const std::list &options); + +private: + bool suppressConsole; + std::string javaExePath; + std::string javawExePath; + std::string javaDllPath; + std::string javaClientDllPath; + std::string javaServerDllPath; + std::string javaPath; + std::string javaBinPath; + + class PrepareDllPath { + public: + PrepareDllPath(const char *dllDirectory) + : setDllDirectory(0) { + logMsg("PrepareDllPath: %s", dllDirectory); + oldCurDir[0] = '\0'; + + // SetDllDirectory is present since XP SP1, so we have to load it dynamically + HINSTANCE hKernel32 = GetModuleHandle("kernel32"); + if (!hKernel32) { + logErr(true, false, "Cannot load kernel32."); + return; + } + + LPFNSDD setDllDirectory = (LPFNSDD)GetProcAddress(hKernel32, "SetDllDirectoryA"); + if (setDllDirectory) { + setDllDirectory(dllDirectory); + } else { + logErr(true, false, "Cannot find SetDllDirectoryA"); + } + GetCurrentDirectory(MAX_PATH, oldCurDir); + SetCurrentDirectory(dllDirectory); + } + ~PrepareDllPath() { + if (setDllDirectory) { + setDllDirectory(NULL); + } + if (oldCurDir[0]) { + SetCurrentDirectory(oldCurDir); + } + } + private: + typedef BOOL (WINAPI *LPFNSDD)(LPCTSTR lpPathname); + LPFNSDD setDllDirectory; + char oldCurDir[MAX_PATH]; + }; +}; + +#endif /* _JVMLAUNCHER_H */ + diff --git a/platform/o.n.bootstrap/launcher/windows/nbexec.cpp b/platform/o.n.bootstrap/launcher/windows/nbexec.cpp new file mode 100644 index 000000000000..47e490ebe465 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/nbexec.cpp @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#include "platformlauncher.h" +#include "utilsfuncs.h" + +PlatformLauncher launcher; + +extern "C" BOOL APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + case DLL_PROCESS_DETACH: + launcher.onExit(); + break; + } + return TRUE; +} + +volatile int exitStatus = 0; + +void exitHook(int status) { + exitStatus = status; + logMsg("Exit hook called with status %d", status); + // do not handle possible restarts, if we are just CLI-connecting to a running process. + if (status != -252) { + launcher.onExit(); + } + logMsg("Exit hook terminated."); +} + +#define NBEXEC_EXPORT extern "C" __declspec(dllexport) + +NBEXEC_EXPORT int startPlatform(int argc, char *argv[], const char *helpMsg) { + DWORD retCode = 0; + launcher.appendToHelp(helpMsg); + launcher.setSuppressConsole(!isConsoleAttached()); + if (!launcher.start(argv, argc, &retCode)) { + return -1; + } + return retCode; +} + + diff --git a/platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest b/platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest new file mode 100644 index 000000000000..580bb41e424e --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest @@ -0,0 +1,75 @@ + + + + + +nbexec process + + + + + + + + + + + + + + + + + UTF-8 + + + + + + true/PM + PerMonitorV2, PerMonitor, system + + + + + + + + + + + + + diff --git a/platform/o.n.bootstrap/launcher/windows/nbexec.rc b/platform/o.n.bootstrap/launcher/windows/nbexec.rc new file mode 100644 index 000000000000..b0843afe3b43 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/nbexec.rc @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include + +#define FNAME "nbexec.dll" +#define FILETYPE_ID 0x2L + +#include "version.rc" + diff --git a/platform/o.n.bootstrap/launcher/windows/nbexec_exe.rc b/platform/o.n.bootstrap/launcher/windows/nbexec_exe.rc new file mode 100644 index 000000000000..df75c0b3bd69 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/nbexec_exe.rc @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include + +#define FNAME "nbexec.exe" +#define FILETYPE_ID 0x1L + +#include "version.rc" + +// Value MANIFEST_FILE id taken from windres parameter -DMANIFEST_FILE +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST MANIFEST_FILE + diff --git a/platform/o.n.bootstrap/launcher/windows/nbexecexe.cpp b/platform/o.n.bootstrap/launcher/windows/nbexecexe.cpp new file mode 100644 index 000000000000..181a365d1fb4 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/nbexecexe.cpp @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#include +#include "nbexecloader.h" + +int main(int argc, char *argv[]) { + checkLoggingArg(argc, argv, true); + NBExecLoader loader; + + // NBEXEC_DLL specified in preprocessor definitions + return loader.start(NBEXEC_DLL, argc - 1, argv + 1); +} diff --git a/platform/o.n.bootstrap/launcher/windows/nbexecloader.h b/platform/o.n.bootstrap/launcher/windows/nbexecloader.h new file mode 100644 index 000000000000..221a55764c74 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/nbexecloader.h @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _NBEXECLOADER_H +#define _NBEXECLOADER_H + +#include "utilsfuncs.h" + +#define HELP_MSG \ +"\ + --console suppress supppress console output\n\ + --console new open new console for output\n\ +\n" + +class NBExecLoader { + typedef int (*StartPlatform)(int argc, char *argv[], const char *help); + +public: + NBExecLoader() + : hLib(0) { + } + ~NBExecLoader() { + if (hLib) { + FreeLibrary(hLib); + } + } + int start(const char *path, int argc, char *argv[]) { + if (!hLib) { + hLib = LoadLibrary(path); + if (!hLib) { + logErr(true, true, "Cannot load \"%s\".", path); + return -1; + } + } + + StartPlatform startPlatform = (StartPlatform) GetProcAddress(hLib, "startPlatform"); + if (!startPlatform) { + logErr(true, true, "Cannot start platform, failed to find startPlatform() in %s", path); + return -1; + } + logMsg("Starting platform...\n"); + return startPlatform(argc, argv, HELP_MSG); + } + +private: + HMODULE hLib; +}; + +#endif /* _NBEXECLOADER_H */ + diff --git a/platform/o.n.bootstrap/launcher/windows/platformlauncher.cpp b/platform/o.n.bootstrap/launcher/windows/platformlauncher.cpp new file mode 100644 index 000000000000..76fc6fc204f7 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/platformlauncher.cpp @@ -0,0 +1,735 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#include "utilsfuncs.h" +#include "platformlauncher.h" +#include "argnames.h" + +volatile extern int exitStatus; + +using namespace std; + +const char *PlatformLauncher::HELP_MSG = +"\nUsage: launcher {options} arguments\n\ +\n\ +General options:\n\ + --help show this help\n\ + --jdkhome path to JDK\n\ + -J pass to JVM\n\ +\n\ + --cp:p prepend to classpath\n\ + --cp:a append to classpath\n\ +\n\ + --fork-java run java in separate process\n\ + --trace path for launcher log (for trouble shooting)\n\ +\n"; + +const char *PlatformLauncher::REQ_JAVA_VERSION = "1.8"; + +const char *PlatformLauncher::OPT_JDK_HOME = "-Djdk.home="; +const char *PlatformLauncher::OPT_NB_PLATFORM_HOME = "-Dnetbeans.home="; +const char *PlatformLauncher::OPT_NB_CLUSTERS = "-Dnetbeans.dirs="; +const char *PlatformLauncher::OPT_NB_USERDIR = "-Dnetbeans.user="; +const char *PlatformLauncher::OPT_DEFAULT_USERDIR_ROOT = "-Dnetbeans.default_userdir_root="; +const char *PlatformLauncher::OPT_HEAP_DUMP = "-XX:+HeapDumpOnOutOfMemoryError"; +const char *PlatformLauncher::OPT_HEAP_DUMP_PATH = "-XX:HeapDumpPath="; +const char *PlatformLauncher::OPT_JAVA_SECURITY_MANAGER_ALLOW = "-Djava.security.manager=allow"; +const char *PlatformLauncher::OPT_KEEP_WORKING_SET_ON_MINIMIZE = "-Dsun.awt.keepWorkingSetOnMinimize=true"; +const char *PlatformLauncher::OPT_CLASS_PATH = "-Djava.class.path="; +const char *PlatformLauncher::OPT_SPLASH = "-splash:"; +const char *PlatformLauncher::OPT_SPLASH_PATH = "\\var\\cache\\splash.png"; + +const char *PlatformLauncher::HEAP_DUMP_PATH = "\\var\\log\\heapdump.hprof"; +const char *PlatformLauncher::RESTART_FILE_PATH = "\\var\\restart"; + +const char *PlatformLauncher::UPDATER_MAIN_CLASS = "org/netbeans/updater/UpdaterFrame"; +const char *PlatformLauncher::IDE_MAIN_CLASS = "org/netbeans/Main"; + +PlatformLauncher::PlatformLauncher() + : separateProcess(false) + , suppressConsole(false) + , heapDumpPathOptFound(false) + , nosplash(false) + , exiting(false) { +} + +PlatformLauncher::PlatformLauncher(const PlatformLauncher& orig) { +} + +PlatformLauncher::~PlatformLauncher() { +} + +bool PlatformLauncher::start(char* argv[], int argc, DWORD *retCode) { + if (!checkLoggingArg(argc, argv, false) || !initPlatformDir() || !parseArgs(argc, argv)) { + return false; + } + disableFolderVirtualization(GetCurrentProcess()); + + if (jdkhome.empty()) { + if (!jvmLauncher.initialize(REQ_JAVA_VERSION)) { + logErr(false, true, "Cannot find Java %s or higher.", REQ_JAVA_VERSION); + return false; + } + } + jvmLauncher.getJavaPath(jdkhome); + + deleteNewClustersFile(); + prepareOptions(); + + if (nextAction.empty()) { + if (shouldAutoUpdateClusters(true)) { + // run updater + if (!run(true, retCode)) { + return false; + } + } + + while (true) { + // run app + if (!run(false, retCode)) { + return false; + } + + if (shouldAutoUpdateClusters(false)) { + // run updater + if (!run(true, retCode)) { + return false; + } + } else if (!restartRequested()) { + break; + } + } + } else { + if (nextAction == ARG_NAME_LA_START_APP) { + return run(false, retCode); + } else if (nextAction == ARG_NAME_LA_START_AU) { + if (shouldAutoUpdateClusters(false)) { + return run(true, retCode); + } + } else { + logErr(false, true, "We should not get here."); + return false; + } + } + + return true; +} + +bool PlatformLauncher::run(bool updater, DWORD *retCode) { + logMsg(updater ? "Starting updater..." : "Starting application..."); + constructClassPath(updater); + const char *mainClass; + if (updater) { + mainClass = UPDATER_MAIN_CLASS; + nextAction = ARG_NAME_LA_START_APP; + } else { + DeleteFile((userDir + RESTART_FILE_PATH).c_str()); + mainClass = bootclass.empty() ? IDE_MAIN_CLASS : bootclass.c_str(); + nextAction = ARG_NAME_LA_START_AU; + } + + string option = OPT_NB_CLUSTERS; + option += auClusters.empty() ? clusters : auClusters; + javaOptions.push_back(option); + + option = OPT_CLASS_PATH; + option += classPath; + javaOptions.push_back(option); + + jvmLauncher.setSuppressConsole(suppressConsole); + bool rc = jvmLauncher.start(mainClass, progArgs, javaOptions, separateProcess, retCode); + if (!separateProcess) { + exit(0); + } + + javaOptions.pop_back(); + javaOptions.pop_back(); + return rc; +} + + + +bool PlatformLauncher::initPlatformDir() { + char path[MAX_PATH] = ""; + getCurrentModulePath(path, MAX_PATH); + logMsg("Module: %s", path); + char *bslash = strrchr(path, '\\'); + if (!bslash) { + return false; + } + *bslash = '\0'; + bslash = strrchr(path, '\\'); + if (!bslash) { + return false; + } + *bslash = '\0'; + clusters = platformDir = path; + logMsg("Platform dir: %s", platformDir.c_str()); + return true; +} + +bool PlatformLauncher::parseArgs(int argc, char *argv[]) { +#define CHECK_ARG \ + if (i+1 == argc) {\ + logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]);\ + return false;\ + } + + logMsg("Parsing arguments:"); + for (int i = 0; i < argc; i++) { + logMsg("\t%s", argv[i]); + } + + for (int i = 0; i < argc; i++) { + if (strcmp(ARG_NAME_SEPAR_PROC, argv[i]) == 0) { + separateProcess = true; + logMsg("Run Java in separater process"); + } else if (strcmp(ARG_NAME_LAUNCHER_LOG, argv[i]) == 0) { + CHECK_ARG; + i++; + } else if (strcmp(ARG_NAME_LA_START_APP, argv[i]) == 0 + || strcmp(ARG_NAME_LA_START_AU, argv[i]) == 0) { + nextAction = argv[i]; + logMsg("Next launcher action: %s", nextAction.c_str()); + } else if (strcmp(ARG_NAME_LA_PPID, argv[i]) == 0) { + CHECK_ARG; + suppressConsole = false; + parentProcID = argv[++i]; + logMsg("Parent process ID found: %s", parentProcID.c_str()); + } else if (strcmp(ARG_NAME_USER_DIR, argv[i]) == 0) { + CHECK_ARG; + char tmp[MAX_PATH + 1] = {0}; + strncpy(tmp, argv[++i], MAX_PATH); + if (strcmp(tmp, "memory") != 0 && !normalizePath(tmp, MAX_PATH)) { + logErr(false, true, "User directory path \"%s\" is not valid.", argv[i]); + return false; + } + userDir = tmp; + logMsg("User dir: %s", userDir.c_str()); + } else if (strcmp(ARG_DEFAULT_USER_DIR_ROOT, argv[i]) == 0) { + CHECK_ARG; + char tmp[MAX_PATH + 1] = {0}; + strncpy(tmp, argv[++i], MAX_PATH); + if (strcmp(tmp, "memory") != 0 && !normalizePath(tmp, MAX_PATH)) { + logErr(false, true, "Default User directory path \"%s\" is not valid.", argv[i]); + return false; + } + defaultUserDirRoot = tmp; + logMsg("Default Userdir root: %s", defaultUserDirRoot.c_str()); + } else if (strcmp(ARG_NAME_CLUSTERS, argv[i]) == 0) { + CHECK_ARG; + clusters = argv[++i]; + } else if (strcmp(ARG_NAME_BOOTCLASS, argv[i]) == 0) { + CHECK_ARG; + bootclass = argv[++i]; + } else if (strcmp(ARG_NAME_JDKHOME, argv[i]) == 0) { + CHECK_ARG; + if (jdkhome.empty()) { + jdkhome = argv[++i]; + if (!jvmLauncher.initialize(jdkhome.c_str())) { + logMsg("Cannot locate java installation in specified jdkhome: %s", jdkhome.c_str()); + string errMsg = "Cannot locate java installation in specified jdkhome:\n"; + errMsg += jdkhome; + errMsg += "\nDo you want to try to use default version?"; + jdkhome = ""; + if (::MessageBox(NULL, errMsg.c_str(), "Invalid jdkhome specified", MB_ICONQUESTION | MB_YESNO) == IDNO) { + return false; + } + } + } else { + i++; + } + } else if (strcmp(ARG_NAME_CP_PREPEND, argv[i]) == 0 + || strcmp(ARG_NAME_CP_PREPEND + 1, argv[i]) == 0) { + CHECK_ARG; + cpBefore += argv[++i]; + } else if (strcmp(ARG_NAME_CP_APPEND, argv[i]) == 0 + || strcmp(ARG_NAME_CP_APPEND + 1, argv[i]) == 0 + || strncmp(ARG_NAME_CP_APPEND + 1, argv[i], 3) == 0 + || strncmp(ARG_NAME_CP_APPEND, argv[i], 4) == 0) { + CHECK_ARG; + cpAfter += argv[++i]; + } else if (strncmp("-J", argv[i], 2) == 0) { + javaOptions.push_back(argv[i] + 2); + if (strncmp(argv[i] + 2, OPT_HEAP_DUMP_PATH, strlen(OPT_HEAP_DUMP_PATH)) == 0) { + heapDumpPathOptFound = true; + } + } else { + if (strcmp(argv[i], "-h") == 0 + || strcmp(argv[i], "-help") == 0 + || strcmp(argv[i], "--help") == 0 + || strcmp(argv[i], "/?") == 0) { + printToConsole(HELP_MSG); + if (!appendHelp.empty()) { + printToConsole(appendHelp.c_str()); + } + } else if (strcmp(ARG_NAME_NOSPLASH, argv[i]) == 0) { + nosplash = true; + } + progArgs.push_back(argv[i]); + } + } + return true; +} + +bool PlatformLauncher::processAutoUpdateCL() { + logMsg("processAutoUpdateCL()..."); + if (userDir.empty()) { + logMsg("\tuserdir empty, quiting"); + return false; + } + string listPath = userDir; + listPath += "\\update\\download\\netbeans.dirs"; + + WIN32_FIND_DATA fd = {0}; + HANDLE hFind = 0; + hFind = FindFirstFile(listPath.c_str(), &fd); + if (hFind == INVALID_HANDLE_VALUE) { + logMsg("File \"%s\" does not exist", listPath.c_str()); + return false; + } + FindClose(hFind); + + FILE *file = fopen(listPath.c_str(), "r"); + if (!file) { + logErr(true, false, "Cannot open file %s", listPath.c_str()); + return false; + } + + int len = fd.nFileSizeLow + 1; + char *str = new char[len]; + if (!fgets(str, len, file)) { + fclose(file); + delete[] str; + logErr(true, false, "Cannot read from file %s", listPath.c_str()); + return false; + } + len = strlen(str) - 1; + if (str[len] == '\n') { + str[len] = '\0'; + } + + auClusters = str; + fclose(file); + delete[] str; + return true; +} + +void PlatformLauncher::deleteNewClustersFile() { + logMsg("deleteNewClustersFile()..."); + if (userDir.empty()) { + logMsg("\tuserdir empty, quiting"); + return; + } + string listPath = userDir; + listPath += "\\update\\download\\netbeans.dirs"; + + if (fileExists(listPath.c_str())) { + DeleteFileA(listPath.c_str()); + logMsg("%s file deleted.", listPath.c_str()); + } +} + +// check if new updater exists, if exists install it (replace old one) and remove ...\new_updater directory +bool PlatformLauncher::checkForNewUpdater(const char *basePath) { + logMsg("checkForNewUpdater() at %s", basePath); + BOOL removeDir = false; + string srcPath = basePath; + srcPath += "\\update\\new_updater\\updater.jar"; + WIN32_FIND_DATA fd = {0}; + HANDLE hFind = FindFirstFile(srcPath.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + logMsg("New updater found: %s", srcPath.c_str()); + FindClose(hFind); + string destPath = basePath; + destPath += "\\modules\\ext\\updater.jar"; + createPath(destPath.c_str()); + + int i = 0; + while (true) { + if (MoveFileEx(srcPath.c_str(), destPath.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { + break; + } + if (exiting || ++i > 10) { + logErr(true, false, "Failed to move \"%s\" to \"%s\"", srcPath.c_str(), destPath.c_str()); + return false; + } + logErr(true, false, "Failed to move \"%s\" to \"%s\", trying to wait", srcPath.c_str(), destPath.c_str()); + Sleep(100); + } + logMsg("New updater successfully moved from \"%s\" to \"%s\"", srcPath.c_str(), destPath.c_str()); + removeDir = true; + } else { + logMsg("No new updater at %s", srcPath.c_str()); + } + string locPath = basePath; + locPath += "\\update\\new_updater\\updater_*.jar"; + hFind = FindFirstFile(locPath.c_str(), &fd); + while (hFind != INVALID_HANDLE_VALUE) { + string destPath = basePath; + string name = fd.cFileName; + logMsg("New updater localization found: %s", name.c_str()); + destPath += "\\modules\\ext\\locale\\"; + destPath += name; + + string fromPath = basePath; + fromPath += "\\update\\new_updater\\"; + fromPath += name; + + createPath(destPath.c_str()); + + int i = 0; + while (true) { + if (MoveFileEx(fromPath.c_str(), destPath.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { + break; + } + if (exiting || ++i > 10) { + logErr(true, false, "Failed to move \"%s\" to \"%s\"", fromPath.c_str(), destPath.c_str()); + return false; + } + logErr(true, false, "Failed to move \"%s\" to \"%s\", trying to wait", fromPath.c_str(), destPath.c_str()); + Sleep(100); + } + logMsg("New updater successfully moved from \"%s\" to \"%s\"", fromPath.c_str(), destPath.c_str()); + removeDir = true; + + if (!FindNextFile(hFind, &fd)) { + break; + } + } + FindClose(hFind); + + if (removeDir) { + srcPath.erase(srcPath.rfind('\\')); + logMsg("Removing directory \"%s\"", srcPath.c_str()); + if (!RemoveDirectory(srcPath.c_str())) { + logErr(true, false, "Failed to remove directory \"%s\"", srcPath.c_str()); + } + } + return true; +} + +bool PlatformLauncher::shouldAutoUpdate(bool firstStart, const char *basePath) { + // The logic is following: + // if there is an NBM for installation then run updater + // unless it is not a first start and we asked to install later (on next start) + + // then also check if last run left list of modules to disable/uninstall and + // did not mark them to be deactivated later (on next start) + string path = basePath; + path += "\\update\\download\\*.nbm"; + logMsg("Checking for updates: %s", path.c_str()); + WIN32_FIND_DATA fd; + HANDLE hFindNbms = FindFirstFile(path.c_str(), &fd); + if (hFindNbms != INVALID_HANDLE_VALUE) { + logMsg("Some updates found at %s", path.c_str()); + FindClose(hFindNbms); + } else { + //also check for OSGi jars if *.nbm not found + path = basePath; + path += "\\update\\download\\*.jar"; + hFindNbms = FindFirstFile(path.c_str(), &fd); + if (hFindNbms != INVALID_HANDLE_VALUE) { + logMsg("Some OSGi updates found at %s", path.c_str()); + FindClose(hFindNbms); + } + } + + path = basePath; + path += "\\update\\download\\install_later.xml"; + HANDLE hFind = FindFirstFile(path.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + logMsg("install_later.xml found: %s", path.c_str()); + FindClose(hFind); + } + + if (hFindNbms != INVALID_HANDLE_VALUE && (firstStart || hFind == INVALID_HANDLE_VALUE)) { + return true; + } + + path = basePath; + path += "\\update\\deactivate\\deactivate_later.txt"; + hFind = FindFirstFile(path.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + logMsg("deactivate_later.txt found: %s", path.c_str()); + FindClose(hFind); + } + + if (firstStart || hFind == INVALID_HANDLE_VALUE) { + path = basePath; + path += "\\update\\deactivate\\to_disable.txt"; + hFind = FindFirstFile(path.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + logMsg("to_disable.txt found: %s", path.c_str()); + FindClose(hFind); + return true; + } + + path = basePath; + path += "\\update\\deactivate\\to_uninstall.txt"; + hFind = FindFirstFile(path.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + logMsg("to_uninstall.txt found: %s", path.c_str()); + FindClose(hFind); + return true; + } + } + + return false; +} + +bool PlatformLauncher::shouldAutoUpdateClusters(bool firstStart) { + bool runUpdater = false; + string cl = processAutoUpdateCL() ? auClusters : clusters; + checkForNewUpdater(platformDir.c_str()); + runUpdater = shouldAutoUpdate(firstStart, platformDir.c_str()); + + const char delim = ';'; + string::size_type start = cl.find_first_not_of(delim, 0); + string::size_type end = cl.find_first_of(delim, start); + while (string::npos != end || string::npos != start) { + string cluster = cl.substr(start, end - start); + checkForNewUpdater(cluster.c_str()); + if (!runUpdater) { + runUpdater = shouldAutoUpdate(firstStart, cluster.c_str()); + } + start = cl.find_first_not_of(delim, end); + end = cl.find_first_of(delim, start); + } + + checkForNewUpdater(userDir.c_str()); + if (!runUpdater) { + runUpdater = shouldAutoUpdate(firstStart, userDir.c_str()); + } + return runUpdater; +} + +void PlatformLauncher::prepareOptions() { + string option = OPT_JDK_HOME; + option += jdkhome; + javaOptions.push_back(option); + + if (!nosplash) { + string splashPath = userDir; + splashPath += OPT_SPLASH_PATH; + if (fileExists(splashPath.c_str())) { + javaOptions.push_back(OPT_SPLASH + splashPath); + } + } + + option = OPT_NB_PLATFORM_HOME; + option += platformDir; + javaOptions.push_back(option); + + option = OPT_NB_USERDIR; + option += userDir; + javaOptions.push_back(option); + + option = OPT_DEFAULT_USERDIR_ROOT; + option += defaultUserDirRoot; + javaOptions.push_back(option); + + option = OPT_HEAP_DUMP; + javaOptions.push_back(option); + + if (!heapDumpPathOptFound) { + option = OPT_HEAP_DUMP_PATH; + option += userDir; + option += HEAP_DUMP_PATH; + javaOptions.push_back(option); + // rename old heap dump to .old + string heapdumpfile = userDir + HEAP_DUMP_PATH; + if (fileExists(heapdumpfile.c_str())) { + string heapdumpfileold = heapdumpfile + ".old"; + if (fileExists(heapdumpfileold.c_str())) { + DeleteFileA(heapdumpfileold.c_str()); + } + MoveFile (heapdumpfile.c_str(), heapdumpfileold.c_str()); + } + } + + option = OPT_KEEP_WORKING_SET_ON_MINIMIZE; + javaOptions.push_back(option); + + option = OPT_JAVA_SECURITY_MANAGER_ALLOW; + javaOptions.push_back(option); +} + +string & PlatformLauncher::constructClassPath(bool runUpdater) { + logMsg("constructClassPath()"); + addedToCP.clear(); + classPath = cpBefore; + + addJarsToClassPathFrom(userDir.c_str()); + addJarsToClassPathFrom(platformDir.c_str()); + + if (runUpdater) { + const char *baseUpdaterPath = userDir.c_str(); + string updaterPath = userDir + "\\modules\\ext\\updater.jar"; + + // if user updater does not exist, use updater from platform + if (!fileExists(updaterPath.c_str())) { + baseUpdaterPath = platformDir.c_str(); + updaterPath = platformDir + "\\modules\\ext\\updater.jar"; + } + + addToClassPath(updaterPath.c_str(), false); + addFilesToClassPath(baseUpdaterPath, "\\modules\\ext\\locale", "updater_*.jar"); + } + + addToClassPath((jdkhome + "\\lib\\dt.jar").c_str(), true); + addToClassPath((jdkhome + "\\lib\\tools.jar").c_str(), true); + + if (!cpAfter.empty()) { + addToClassPath(cpAfter.c_str(), false); + } + logMsg("ClassPath: %s", classPath.c_str()); + return classPath; +} + +void PlatformLauncher::addJarsToClassPathFrom(const char *dir) { + addFilesToClassPath(dir, "lib\\patches", "*.jar"); + addFilesToClassPath(dir, "lib\\patches", "*.zip"); + + addFilesToClassPath(dir, "lib", "*.jar"); + addFilesToClassPath(dir, "lib", "*.zip"); + + addFilesToClassPath(dir, "lib\\locale", "*.jar"); + addFilesToClassPath(dir, "lib\\locale", "*.zip"); +} + +void PlatformLauncher::addFilesToClassPath(const char *dir, const char *subdir, const char *pattern) { + logMsg("addFilesToClassPath()\n\tdir: %s\n\tsubdir: %s\n\tpattern: %s", dir, subdir, pattern); + string path = dir; + path += '\\'; + path += subdir; + path += '\\'; + + WIN32_FIND_DATA fd = {0}; + string patternPath = path + pattern; + HANDLE hFind = FindFirstFile(patternPath.c_str(), &fd); + if (hFind == INVALID_HANDLE_VALUE) { + logMsg("Nothing found (%s)", patternPath.c_str()); + return; + } + do { + string name = subdir; + name += fd.cFileName; + string fullName = path + fd.cFileName; + if (addedToCP.insert(name).second) { + addToClassPath(fullName.c_str()); + } else { + logMsg("\"%s\" already added, skipping \"%s\"", name.c_str(), fullName.c_str()); + } + } while (FindNextFile(hFind, &fd)); + FindClose(hFind); +} + +void PlatformLauncher::addToClassPath(const char *path, bool onlyIfExists) { + logMsg("addToClassPath()\n\tpath: %s\n\tonlyIfExists: %s", path, onlyIfExists ? "true" : "false"); + if (onlyIfExists && !fileExists(path)) { + return; + } + + if (!classPath.empty()) { + classPath += ';'; + } + classPath += path; +} + +void PlatformLauncher::appendToHelp(const char *msg) { + if (msg) { + appendHelp = msg; + } +} + +bool PlatformLauncher::restartRequested() { + return fileExists((userDir + RESTART_FILE_PATH).c_str()); +} + +void PlatformLauncher::onExit() { + logMsg("onExit()"); + if (exitStatus == -252) { + logMsg("Exiting from CLI client, will not restart."); + return; + } + + if (exiting) { + logMsg("Already exiting, no need to schedule restart"); + return; + } + + exiting = true; + + if (separateProcess) { + logMsg("JVM in separate process, no need to restart"); + return; + } + + bool restart = (nextAction == ARG_NAME_LA_START_APP || (nextAction == ARG_NAME_LA_START_AU && shouldAutoUpdateClusters(false))); + if (!restart && restartRequested()) { + restart = true; + nextAction = ARG_NAME_LA_START_APP; + } + + if (restart) { + string cmdLine = GetCommandLine(); + logMsg("Old command line: %s", cmdLine.c_str()); + string::size_type bslashPos = cmdLine.find_last_of('\\'); + string::size_type pos = cmdLine.find(ARG_NAME_LA_START_APP); + if ((bslashPos == string::npos || bslashPos < pos) && pos != string::npos) { + cmdLine.erase(pos, strlen(ARG_NAME_LA_START_APP)); + } + pos = cmdLine.find(ARG_NAME_LA_START_AU); + if ((bslashPos == string::npos || bslashPos < pos) && pos != string::npos) { + cmdLine.erase(pos, strlen(ARG_NAME_LA_START_AU)); + } + + if (*cmdLine.rbegin() != ' ') { + cmdLine += ' '; + } + if (!parentProcID.empty() && cmdLine.find(ARG_NAME_LA_PPID) == string::npos) { + cmdLine += ARG_NAME_LA_PPID; + cmdLine += ' '; + cmdLine += parentProcID; + } + + if (*cmdLine.rbegin() != ' ') { + cmdLine += ' '; + } + cmdLine += nextAction; + + logMsg("New command line: %s", cmdLine.c_str()); + char cmdLineStr[32 * 1024] = ""; + strcpy(cmdLineStr, cmdLine.c_str()); + STARTUPINFO si = {0}; + PROCESS_INFORMATION pi = {0}; + si.cb = sizeof(STARTUPINFO); + + if (!CreateProcess(NULL, cmdLineStr, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { + logErr(true, true, "Failed to create process."); + return; + } + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } +} diff --git a/platform/o.n.bootstrap/launcher/windows/platformlauncher.h b/platform/o.n.bootstrap/launcher/windows/platformlauncher.h new file mode 100644 index 000000000000..ac3e7be4b706 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/platformlauncher.h @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#ifndef _PLATFORMLAUNCHER_H +#define _PLATFORMLAUNCHER_H + +#include "jvmlauncher.h" +#include +#include +#include + +class PlatformLauncher { + static const char *REQ_JAVA_VERSION; + static const char *HELP_MSG; + + static const char *HEAP_DUMP_PATH; + static const char *RESTART_FILE_PATH; + + static const char *OPT_JDK_HOME; + static const char *OPT_NB_PLATFORM_HOME; + static const char *OPT_NB_CLUSTERS; + static const char *OPT_NB_USERDIR; + static const char *OPT_DEFAULT_USERDIR_ROOT; + static const char *OPT_HEAP_DUMP; + static const char *OPT_HEAP_DUMP_PATH; + static const char *OPT_JAVA_SECURITY_MANAGER_ALLOW; + static const char *OPT_KEEP_WORKING_SET_ON_MINIMIZE; + static const char *OPT_CLASS_PATH; + static const char *OPT_SPLASH; + static const char *OPT_SPLASH_PATH; + + static const char *UPDATER_MAIN_CLASS; + static const char *IDE_MAIN_CLASS; + + +public: + PlatformLauncher(); + virtual ~PlatformLauncher(); + + bool start(char* argv[], int argc, DWORD *retCode); + void appendToHelp(const char *msg); + void onExit(); + + void setSuppressConsole(bool val) { + suppressConsole = val; + } + +private: + PlatformLauncher(const PlatformLauncher& orig); + bool parseArgs(int argc, char *argv[]); + bool initPlatformDir(); + bool processAutoUpdateCL(); + void deleteNewClustersFile(); + bool checkForNewUpdater(const char *basePath); + bool shouldAutoUpdate(bool firstStart, const char *basePath); + bool shouldAutoUpdateClusters(bool firstStart); + void prepareOptions(); + std::string & constructClassPath(bool runUpdater); + void addFilesToClassPath(const char *dir, const char *subdir, const char *pattern); + void addToClassPath(const char *path, bool onlyIfExists = false); + void addJarsToClassPathFrom(const char *dir); + bool run(bool updater, DWORD *retCode); + bool restartRequested(); + +private: + bool separateProcess; + bool suppressConsole; + bool heapDumpPathOptFound; + bool nosplash; + bool exiting; + std::string platformDir; + std::string userDir; + std::string defaultUserDirRoot; + std::string clusters; + std::string bootclass; + std::string jdkhome; + std::string cpBefore; + std::string cpAfter; + std::string auClusters; + std::string nextAction; + std::string parentProcID; + + std::list javaOptions; + std::list launcherOptions; + std::list progArgs; + JvmLauncher jvmLauncher; + std::set addedToCP; + std::string classPath; + std::string appendHelp; +}; + +#endif /* _PLATFORMLAUNCHER_H */ + diff --git a/platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp b/platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp new file mode 100644 index 000000000000..16c6ce07d81d --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp @@ -0,0 +1,464 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#ifndef KEY_WOW64_64KEY +#define KEY_WOW64_64KEY 0x0100 +#endif + +#include "utilsfuncs.h" +#include "argnames.h" +#include +#include + +using namespace std; + +bool disableFolderVirtualization(HANDLE hProcess) { + OSVERSIONINFO osvi = {0}; + osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + if (GetVersionEx(&osvi) && osvi.dwMajorVersion == 6) // check it is Win VISTA + { + HANDLE hToken; + if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken)) { + DWORD tokenInfoVal = 0; + if (!SetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) 24, &tokenInfoVal, sizeof (DWORD))) { + // invalid token information class (24) is OK, it means there is no folder virtualization on current system + if (GetLastError() != ERROR_INVALID_PARAMETER) { + logErr(true, true, "Failed to set token information."); + return false; + } + } + CloseHandle(hToken); + } else { + logErr(true, true, "Failed to open process token."); + return false; + } + } + return true; +} + +bool getStringFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, string &value) { + return getStringFromRegistryEx(rootKey, keyName, valueName, value, false); +} + +bool getStringFromRegistry64bit(HKEY rootKey, const char *keyName, const char *valueName, string &value) { + return getStringFromRegistryEx(rootKey, keyName, valueName, value, true); +} + + + +bool getStringFromRegistryEx(HKEY rootKey, const char *keyName, const char *valueName, string &value, bool read64bit) { + logMsg("getStringFromRegistry()\n\tkeyName: %s\n\tvalueName: %s", keyName, valueName); + HKEY hKey = 0; + if (RegOpenKeyEx(rootKey, keyName, 0, KEY_READ | (read64bit ? KEY_WOW64_64KEY : 0), &hKey) == ERROR_SUCCESS) { + DWORD valSize = 4096; + DWORD type = 0; + char val[4096] = ""; + if (RegQueryValueEx(hKey, valueName, 0, &type, (BYTE *) val, &valSize) == ERROR_SUCCESS + && type == REG_SZ) { + logMsg("%s: %s", valueName, val); + RegCloseKey(hKey); + value = val; + return true; + } else { + logErr(true, false, "RegQueryValueEx() failed."); + } + RegCloseKey(hKey); + } else { + logErr(true, false, "RegOpenKeyEx() failed."); + } + return false; +} + +bool getDwordFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, DWORD &value) { + logMsg("getDwordFromRegistry()\n\tkeyName: %s\n\tvalueName: %s", keyName, valueName); + HKEY hKey = 0; + if (RegOpenKeyEx(rootKey, keyName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + DWORD valSize = sizeof(DWORD); + DWORD type = 0; + if (RegQueryValueEx(hKey, valueName, 0, &type, (BYTE *) &value, &valSize) == ERROR_SUCCESS + && type == REG_DWORD) { + logMsg("%s: %u", valueName, value); + RegCloseKey(hKey); + return true; + } else { + logErr(true, false, "RegQueryValueEx() failed."); + } + RegCloseKey(hKey); + } else { + logErr(true, false, "RegOpenKeyEx() failed."); + } + return false; +} + +bool dirExists(const char *path) { + WIN32_FIND_DATA fd = {0}; + HANDLE hFind = 0; + hFind = FindFirstFile(path, &fd); + if (hFind == INVALID_HANDLE_VALUE) { + logMsg("Dir \"%s\" does not exist", path); + return false; + } + logMsg("Dir \"%s\" exists", path); + FindClose(hFind); + return (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; +} + +bool fileExists(const char *path) { + WIN32_FIND_DATA fd = {0}; + HANDLE hFind = 0; + hFind = FindFirstFile(path, &fd); + if (hFind == INVALID_HANDLE_VALUE) { + logMsg("File \"%s\" does not exist", path); + return false; + } + + logMsg("File \"%s\" exists", path); + FindClose(hFind); + return true; +} + +bool normalizePath(char *path, int len) { + char tmp[MAX_PATH] = ""; + int i = 0; + while (path[i] && i < MAX_PATH - 1) { + tmp[i] = path[i] == '/' ? '\\' : path[i]; + i++; + } + tmp[i] = '\0'; + return _fullpath(path, tmp, len) != NULL; +} + +bool createPath(const char *path) { + logMsg("Creating directory \"%s\"", path); + char dir[MAX_PATH] = ""; + const char *sep = strchr(path, '\\'); + while (sep) { + strncpy(dir, path, sep - path); + if (!CreateDirectory(dir, 0) && GetLastError() != ERROR_ALREADY_EXISTS) { + logErr(true, false, "Failed to create directory %s", dir); + return false; + } + sep = strchr(sep + 1, '\\'); + } + return true; +} + + +char * getCurrentModulePath(char *path, int pathLen) { + MEMORY_BASIC_INFORMATION mbi; + static int dummy; + VirtualQuery(&dummy, &mbi, sizeof (mbi)); + HMODULE hModule = (HMODULE) mbi.AllocationBase; + GetModuleFileName(hModule, path, pathLen); + return path; +} + +char * skipWhitespaces(char *str) { + while (*str != '\0' && (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r')) { + str++; + } + return str; +} + +char * trimWhitespaces(char *str) { + char *end = str + strlen(str) - 1; + while (end >= str && (*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r')) { + *end = '\0'; + end--; + } + return end; +} + +char* getSysError(char *str, int strSize) { + int err = GetLastError(); + LPTSTR lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) & lpMsgBuf, + 0, + NULL + ); + LPTSTR tmp = strchr(lpMsgBuf, '\r'); + if (tmp != NULL) { + *tmp = '\0'; + } + + _snprintf(str, strSize, " %s (%u)", lpMsgBuf, err); + LocalFree(lpMsgBuf); + return str; +} + +string gLogFileName; + +void logV(bool appendSysError, bool showMsgBox, const char *format, va_list args) { + char msg[4096] = ""; + vsnprintf(msg, 4096, format, args); + + if (appendSysError) { + char sysErr[512] = ""; + getSysError(sysErr, 512); + strncat(msg, sysErr, 4096 - strlen(msg)); + } + + if (!gLogFileName.empty()) { + FILE *file = fopen(gLogFileName.c_str(), "a"); + if (file) { + fprintf(file, "%s\n", msg); + fclose(file); + } + } + + if (showMsgBox) { + ::MessageBox(NULL, msg, "Error", MB_OK | MB_ICONSTOP); + } +} + +void logErr(bool appendSysError, bool showMsgBox, const char *format, ...) { + va_list args; + va_start(args, format); + logV(appendSysError, showMsgBox, format, args); +} + +void logMsg(const char *format, ...) { + va_list args; + va_start(args, format); + logV(false, false, format, args); +} + +bool restarting(int argc, char *argv[]) { + for (int i = 0; i < argc; i++) { + if (strcmp(ARG_NAME_LA_START_APP, argv[i]) == 0 || strcmp(ARG_NAME_LA_START_AU, argv[i]) == 0) { + return true; + } + } + return false; +} + +bool checkLoggingArg(int argc, char *argv[], bool delFile) { + for (int i = 0; i < argc; i++) { + if (strcmp(ARG_NAME_LAUNCHER_LOG, argv[i]) == 0) { + if (i + 1 == argc) { + logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]); + return false; + } + gLogFileName = argv[++i]; + // if we are restarting, keep log file + if (delFile && !restarting(argc, argv)) { + DeleteFile(gLogFileName.c_str()); + } + break; + } + } + return true; +} + +void setConsoleCodepage() { + /* The Windows console (cmd) has its own code page setting that's usually different from the + system and user code page, e.g. on US Windows the console will use code page 437 while the + rest of the system uses 1252. Setting the console code page here to UTF-8 makes Unicode + characters printed from the application appear correctly. Since the launcher itself also runs + with UTF-8 as its code page (specified in the application manifest), this also makes log + messages from the launchers appear correctly, e.g. when printing paths that may have Unicode + characters in them. Note that if we attached to an existing console, the modified code page + setting will persist after the launcher exits. */ + SetConsoleOutputCP(CP_UTF8); + SetConsoleCP(CP_UTF8); +} + +bool setupProcess(int &argc, char *argv[], DWORD &parentProcID, const char *attachMsg) { +#define CHECK_ARG \ + if (i+1 == argc) {\ + logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]);\ + return false;\ + } + + parentProcID = 0; + DWORD cmdLineArgPPID = 0; + for (int i = 0; i < argc; i++) { + if (strcmp(ARG_NAME_CONSOLE, argv[i]) == 0) { + CHECK_ARG; + if (strcmp("new", argv[i + 1]) == 0){ + AllocConsole(); + setConsoleCodepage(); + } else if (strcmp("suppress", argv[i + 1]) == 0) { + // nothing, no console should be attached + } else { + logErr(false, true, "Invalid argument for \"%s\" option.", argv[i]); + return false; + } + // remove options + for (int k = i + 2; k < argc; k++) { + argv[k-2] = argv[k]; + } + argc -= 2; + return true; + } else if (strcmp(ARG_NAME_LA_PPID, argv[i]) == 0) { + CHECK_ARG; + char *end = 0; + cmdLineArgPPID = strtoul(argv[++i], &end, 10); + if (cmdLineArgPPID == 0 && *end != '\0') { + logErr(false, true, "Invalid parameter for option %s", ARG_NAME_LA_PPID); + return false; + } + logMsg("Command line arg PPID: %u", cmdLineArgPPID); + break; + } + } +#undef CHECK_ARG + + // default, attach to parent process console if exists + // AttachConsole exists since WinXP, so be nice and do it dynamically + typedef BOOL (WINAPI *LPFAC)(DWORD dwProcessId); + HINSTANCE hKernel32 = GetModuleHandle("kernel32"); + if (hKernel32) { + LPFAC attachConsole = (LPFAC) GetProcAddress(hKernel32, "AttachConsole"); + if (attachConsole) { + if (cmdLineArgPPID) { + if (!attachConsole(cmdLineArgPPID)) { + logErr(true, false, "AttachConsole of PPID: %u failed.", cmdLineArgPPID); + } + } else { + if (!attachConsole((DWORD) -1)) { + logErr(true, false, "AttachConsole of PP failed."); + } else { + getParentProcessID(parentProcID); + setConsoleCodepage(); + if (attachMsg) { + printToConsole(attachMsg); + } + } + } + } else { + logErr(true, false, "GetProcAddress() for AttachConsole failed."); + } + } + return true; +} + +bool isConsoleAttached() { + typedef HWND (WINAPI *GetConsoleWindowT)(); + HINSTANCE hKernel32 = GetModuleHandle("kernel32"); + if (hKernel32) { + GetConsoleWindowT getConsoleWindow = (GetConsoleWindowT) GetProcAddress(hKernel32, "GetConsoleWindow"); + if (getConsoleWindow) { + if (getConsoleWindow() != NULL) { + logMsg("Console is attached."); + return true; + } + } else { + logErr(true, false, "GetProcAddress() for GetConsoleWindow failed."); + } + } + return false; +} + +bool printToConsole(const char *msg) { + FILE *console = fopen("CON", "a"); + if (!console) { + return false; + } + fprintf(console, "%s", msg); + fclose(console); + return false; +} + +bool getParentProcessID(DWORD &id) { + typedef HANDLE (WINAPI * CreateToolhelp32SnapshotT)(DWORD, DWORD); + typedef BOOL (WINAPI * Process32FirstT)(HANDLE, LPPROCESSENTRY32); + typedef BOOL (WINAPI * Process32NextT)(HANDLE, LPPROCESSENTRY32); + + HINSTANCE hKernel32 = GetModuleHandle("kernel32"); + if (!hKernel32) { + return false; + } + + CreateToolhelp32SnapshotT createToolhelp32Snapshot = (CreateToolhelp32SnapshotT) GetProcAddress(hKernel32, "CreateToolhelp32Snapshot"); + Process32FirstT process32First = (Process32FirstT) GetProcAddress(hKernel32, "Process32First"); + Process32NextT process32Next = (Process32NextT) GetProcAddress(hKernel32, "Process32Next"); + + if (createToolhelp32Snapshot == NULL || process32First == NULL || process32Next == NULL) { + logErr(true, false, "Failed to obtain Toolhelp32 functions."); + return false; + } + + HANDLE hSnapshot = createToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hSnapshot == INVALID_HANDLE_VALUE) { + logErr(true, false, "Failed to obtain process snapshot."); + return false; + } + + PROCESSENTRY32 entry = {0}; + entry.dwSize = sizeof (PROCESSENTRY32); + if (!process32First(hSnapshot, &entry)) { + CloseHandle(hSnapshot); + return false; + } + + DWORD curID = GetCurrentProcessId(); + logMsg("Current process ID: %u", curID); + + do { + if (entry.th32ProcessID == curID) { + id = entry.th32ParentProcessID; + logMsg("Parent process ID: %u", id); + CloseHandle(hSnapshot); + return true; + } + } while (process32Next(hSnapshot, &entry)); + + CloseHandle(hSnapshot); + return false; +} + +bool isWow64() +{ + BOOL IsWow64 = FALSE; + typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + LPFN_ISWOW64PROCESS fnIsWow64Process; + + fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process"); + + if (NULL != fnIsWow64Process) + { + if (!fnIsWow64Process(GetCurrentProcess(),&IsWow64)) + { + // handle error + } + } + return IsWow64; +} + +int convertAnsiToUtf8(const char *ansi, char *utf8, int utf8Len) { + const int len = 32*1024; + WCHAR tmp[len] = L""; + if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansi, -1, tmp, len) == 0) + return -1; + if (WideCharToMultiByte(CP_UTF8, 0, tmp, -1, utf8, utf8Len, NULL, NULL) == 0) + return -1; + return 0; +} + diff --git a/platform/o.n.bootstrap/launcher/windows/utilsfuncs.h b/platform/o.n.bootstrap/launcher/windows/utilsfuncs.h new file mode 100644 index 000000000000..6cf172a24db5 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/utilsfuncs.h @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /* + * Author: Tomas Holy + */ + +#ifndef _UTILSFUNCS_H +#define _UTILSFUNCS_H + +#include +#include + +bool isWow64(); +bool disableFolderVirtualization(HANDLE hProcess); +bool getStringFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, std::string &value); +bool getStringFromRegistryEx(HKEY rootKey, const char *keyName, const char *valueName, std::string &value,bool read64bit); +bool getStringFromRegistry64bit(HKEY rootKey, const char *keyName, const char *valueName, std::string &value); +bool getDwordFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, DWORD &value); +bool dirExists(const char *path); +bool fileExists(const char *path); +bool normalizePath(char *path, int len); +bool createPath(const char *path); +char * getCurrentModulePath(char *path, int pathLen); +char * skipWhitespaces(char *str); +char * trimWhitespaces(char *str); +void logMsg(const char *format, ...); +void logErr(bool appendSysError, bool showMsgBox, const char *format, ...); +bool checkLoggingArg(int argc, char *argv[], bool delFile); +bool setupProcess(int &argc, char *argv[], DWORD &parentProcID, const char *attachMsg = 0); +bool printToConsole(const char *msg); +bool getParentProcessID(DWORD &id); +bool isConsoleAttached(); +int convertAnsiToUtf8(const char *ansi, char *utf8, int utf8Len); + +#endif /* _UTILSFUNCS_H */ + diff --git a/platform/o.n.bootstrap/launcher/windows/version.h b/platform/o.n.bootstrap/launcher/windows/version.h new file mode 100644 index 000000000000..26b4461403ba --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/version.h @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#define COMPANY "" +#define COMPONENT "NetBeans Platform Launcher" +#define VER "12.5.0.0" +#define FVER 12,5,0,0 +#define BUILD_ID "28062021" +#define INTERNAL_NAME "nbexec" +#define COPYRIGHT "Based on Apache NetBeans from the Apache Software Foundation and is licensed under Apache License Version 2.0" +#define NAME "NetBeans Platform Launcher" + diff --git a/platform/o.n.bootstrap/launcher/windows/version.rc b/platform/o.n.bootstrap/launcher/windows/version.rc new file mode 100644 index 000000000000..7a516a4c5876 --- /dev/null +++ b/platform/o.n.bootstrap/launcher/windows/version.rc @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include "version.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION FVER + PRODUCTVERSION FVER + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + // FILEOS 0x4 is Win32, 0x40004 is Win32 NT only + FILEOS 0x4L + // FILETYPE should be 0x1 for .exe and 0x2 for .dll + FILETYPE FILETYPE_ID + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", COMPANY "\0" + VALUE "FileDescription", COMPONENT "\0" + VALUE "FileVersion", VER "\0" + VALUE "Full Version", BUILD_ID "\0" + VALUE "InternalName", INTERNAL_NAME "\0" + VALUE "LegalCopyright", COPYRIGHT "\0" + VALUE "OriginalFilename", FNAME "\0" + VALUE "ProductName", NAME "\0" + VALUE "ProductVersion", VER "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END From b8e969aa0f5345a6d94254f09a601b9418c0ecfb Mon Sep 17 00:00:00 2001 From: Neil C Smith Date: Tue, 19 Dec 2023 18:02:27 +0000 Subject: [PATCH 2/2] Update paths and add workflow file to build native launchers. --- .../native-binary-build-launcher.yml | 210 ++++++++++++++++++ .../windows-launcher-src/Makefile.mingw | 12 +- .../windows-launcher-src/app.exe.manifest | 2 +- .../windows-launcher-src/applauncher.cpp | 4 +- .../windows-launcher-src/applauncher.h | 2 +- nb/ide.launcher/windows/Makefile.mingw | 12 +- nb/ide.launcher/windows/nblauncher.cpp | 6 +- nb/ide.launcher/windows/netbeans.exe.manifest | 2 +- .../windows/netbeans64.exe.manifest | 2 +- nb/ide.launcher/windows/version.h | 10 +- .../launcher/windows/Makefile.mingw | 4 +- .../launcher/windows/nbexec.exe.manifest | 2 +- .../o.n.bootstrap/launcher/windows/version.h | 10 +- 13 files changed, 244 insertions(+), 34 deletions(-) create mode 100644 .github/workflows/native-binary-build-launcher.yml diff --git a/.github/workflows/native-binary-build-launcher.yml b/.github/workflows/native-binary-build-launcher.yml new file mode 100644 index 000000000000..2b4ea7b96eb9 --- /dev/null +++ b/.github/workflows/native-binary-build-launcher.yml @@ -0,0 +1,210 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# ---------------------- +# +# This workflow builds the native Windows launchers for the IDE and platform. +# +# The result of the build are files 'launcher-external-sources.zip' +# and 'launcher-external-binaries.zip' which can be downloaded from +# the GitHub Actions UI and prepared for release to be used by the Ant build +# scripts for the NetBeans distribution. +# +# ---------------------- + + +name: NetBeans Native Launcher + + +on: + push: + # Triggers the workflow on push or pull request events but only for + # relevant paths + paths: + - .github/workflows/native-binary-build-launcher.y* + - platform/o.n.bootstrap/launcher/windows/** + - harness/apisupport.harness/windows-launcher-src/** + - nb/ide.launcher/windows/** + + pull_request: + paths: + - .github/workflows/native-binary-build-launcher.y* + - platform/o.n.bootstrap/launcher/windows/** + - harness/apisupport.harness/windows-launcher-src/** + - nb/ide.launcher/windows/** + + # Allows you to run this workflow manually from the Actions tab in GitHub UI + workflow_dispatch: + +# cancel other PR workflow run in the same head-base group if it exists (e.g. during PR syncs) +# if this is not a PR run (no github.head_ref and github.base_ref defined), use an UID as group +concurrency: + group: launcher-${{ github.head_ref || github.run_id }}-${{ github.base_ref }} + cancel-in-progress: true + +jobs: + + source: + + name: Package Sources + runs-on: ubuntu-latest + + steps: + + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + submodules: false + show-progress: false + + - name: Generate source bundle + run: | + SOURCES="nbbuild/build/native/launcher/sources" + mkdir -p ${SOURCES}/platform/o.n.bootstrap/launcher/ + cp -r platform/o.n.bootstrap/launcher/windows/ ${SOURCES}/platform/o.n.bootstrap/launcher/ + mkdir -p ${SOURCES}/harness/apisupport.harness/ + cp -r harness/apisupport.harness/windows-launcher-src/ ${SOURCES}/harness/apisupport.harness/ + mkdir -p ${SOURCES}/nb/ide.launcher/ + cp -r nb/ide.launcher/windows/ ${SOURCES}/nb/ide.launcher/ + cp LICENSE ${SOURCES}/LICENSE + cp NOTICE ${SOURCES}/NOTICE + ls -l -R ${SOURCES} + + - name: Upload native sources + uses: actions/upload-artifact@v3 + with: + name: launcher-external-sources + path: nbbuild/build/native/launcher/sources/ + if-no-files-found: error + + + build-linux: + + name: Build with MinGW + runs-on: ubuntu-latest + needs: source + + steps: + + - name: Install MinGW + run: sudo apt install mingw-w64 mingw-w64-tools + + - name: Download sources + uses: actions/download-artifact@v3 + with: + name: launcher-external-sources + + - name: Build bootstrap binaries + run: | + echo "Building bootstrap binaries" + rm -rf ./build/ + make -f Makefile.mingw + ls -l -R ./build/ + echo "done" + working-directory: platform/o.n.bootstrap/launcher/windows/ + + - name: Upload bootstrap artifacts + uses: actions/upload-artifact@v3 + with: + name: launcher-bootstrap-bin + path: platform/o.n.bootstrap/launcher/windows/build/ + if-no-files-found: error + + - name: Build harness binaries + run: | + echo "Building harness binaries" + rm -rf ./build/ + make -f Makefile.mingw + ls -l -R ./build/ + echo "done" + working-directory: harness/apisupport.harness/windows-launcher-src + + - name: Upload harness artifacts + uses: actions/upload-artifact@v3 + with: + name: launcher-harness-bin + path: harness/apisupport.harness/windows-launcher-src/build/ + if-no-files-found: error + + - name: Build IDE binaries + run: | + echo "Building IDE binaries" + rm -rf ./build/ + make -f Makefile.mingw + ls -l -R ./build/ + echo "done" + working-directory: nb/ide.launcher/windows + + - name: Upload IDE artifacts + uses: actions/upload-artifact@v3 + with: + name: launcher-ide-bin + path: nb/ide.launcher/windows/build/ + if-no-files-found: error + + build-zip-with-build-artifacts: + + name: Package Binaries + runs-on: ubuntu-latest + + # Only run when the platform specific builds are finished + needs: [build-linux] + + steps: + + - name: Create dir structure + run: mkdir -p myfiles/ + + - name: Download artifacts from predecessor jobs + uses: actions/download-artifact@v3 + with: + path: myfiles/ + + - name: Tidy up and display artifacts + run: | + cp myfiles/launcher-external-sources/LICENSE myfiles/LICENSE + cp myfiles/launcher-external-sources/NOTICE myfiles/NOTICE + cp myfiles/*bin/*.exe myfiles/ + cp myfiles/*bin/*.dll myfiles/ + rm -rf myfiles/*-sources/ + rm -rf myfiles/*-bin/ + ls -l -R + + - name: Create BUILDINFO + run: | + BUILDINFO="myfiles/BUILDINFO.txt" + touch "$BUILDINFO" + echo "Apache NetBeans" >> "$BUILDINFO" + echo "" >> "$BUILDINFO" + echo "Binaries in this ZIP are..." >> "$BUILDINFO" + echo "Build by GitHub Actions Workflow: ${GITHUB_WORKFLOW}" >> "$BUILDINFO" + echo "" >> "$BUILDINFO" + echo "Build from:" >> "$BUILDINFO" + echo " Git repo : ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" >> "$BUILDINFO" + echo " Git commit SHA : ${GITHUB_SHA}" >> "$BUILDINFO" + echo " Git ref : ${GITHUB_REF}" >> "$BUILDINFO" + echo "" >> "$BUILDINFO" + echo "Build time UTC : $(date --rfc-3339=seconds --utc)" >> "$BUILDINFO" + echo "" >> "$BUILDINFO" + + - name: Upload bundle + uses: actions/upload-artifact@v3 + with: + name: launcher-external-binaries + path: myfiles/ + if-no-files-found: error diff --git a/harness/apisupport.harness/windows-launcher-src/Makefile.mingw b/harness/apisupport.harness/windows-launcher-src/Makefile.mingw index 866b30dd1e54..0a4dfb6421af 100644 --- a/harness/apisupport.harness/windows-launcher-src/Makefile.mingw +++ b/harness/apisupport.harness/windows-launcher-src/Makefile.mingw @@ -15,8 +15,8 @@ # specific language governing permissions and limitations # under the License. -TMPFLD = ../../../../target/tmp/ -OFLD = ../../../../target/harness/ +TMPFLD = ./build/ +OFLD = ./build/ all: prepfolder app64.exe app.exe @@ -30,12 +30,12 @@ clean: app64.res: app.rc app.exe.manifest x86_64-w64-mingw32-windres -o$(TMPFLD)app64.res -Ocoff -DMANIFEST_FILE=app.exe.manifest app.rc -app64.exe: app.cpp applauncher.cpp app64.res ../bootstrap/utilsfuncs.cpp - x86_64-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec64.dll"' -DARCHITECTURE=64 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh app.cpp -mwindows applauncher.cpp $(TMPFLD)app64.res ../bootstrap/utilsfuncs.cpp ../ide/nblauncher.cpp -I ../bootstrap/ -o$(OFLD)app64.exe -static -lstdc++ -static-libstdc++ -static-libgcc +app64.exe: app.cpp applauncher.cpp app64.res ../../../platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp + x86_64-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec64.dll"' -DARCHITECTURE=64 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh app.cpp -mwindows applauncher.cpp $(TMPFLD)app64.res ../../../platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp ../../../nb/ide.launcher/windows/nblauncher.cpp -I ../../../platform/o.n.bootstrap/launcher/windows/ -o$(OFLD)app64.exe -static -lstdc++ -static-libstdc++ -static-libgcc app.res: app.rc app.exe.manifest i686-w64-mingw32-windres -o$(TMPFLD)app.res -Ocoff -DMANIFEST_FILE=app.exe.manifest app.rc -app.exe: app.cpp applauncher.cpp app.res ../bootstrap/utilsfuncs.cpp - i686-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec.dll"' -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows app.cpp applauncher.cpp $(TMPFLD)app.res ../bootstrap/utilsfuncs.cpp ../ide/nblauncher.cpp -I ../bootstrap/ -o$(OFLD)app.exe -static -lstdc++ -static-libstdc++ -static-libgcc +app.exe: app.cpp applauncher.cpp app.res ../../../platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp + i686-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec.dll"' -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows app.cpp applauncher.cpp $(TMPFLD)app.res ../../../platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp ../../../nb/ide.launcher/windows/nblauncher.cpp -I ../../../platform/o.n.bootstrap/launcher/windows/ -o$(OFLD)app.exe -static -lstdc++ -static-libstdc++ -static-libgcc diff --git a/harness/apisupport.harness/windows-launcher-src/app.exe.manifest b/harness/apisupport.harness/windows-launcher-src/app.exe.manifest index c1843b229a94..789c48dce89d 100644 --- a/harness/apisupport.harness/windows-launcher-src/app.exe.manifest +++ b/harness/apisupport.harness/windows-launcher-src/app.exe.manifest @@ -20,7 +20,7 @@ --> - diff --git a/harness/apisupport.harness/windows-launcher-src/applauncher.cpp b/harness/apisupport.harness/windows-launcher-src/applauncher.cpp index 1fa9d4ee8165..f8163168ce66 100644 --- a/harness/apisupport.harness/windows-launcher-src/applauncher.cpp +++ b/harness/apisupport.harness/windows-launcher-src/applauncher.cpp @@ -21,8 +21,8 @@ */ #include "applauncher.h" -#include "../bootstrap/utilsfuncs.h" -#include "../bootstrap/argnames.h" +#include "../../../platform/o.n.bootstrap/launcher/windows/utilsfuncs.h" +#include "../../../platform/o.n.bootstrap/launcher/windows/argnames.h" using namespace std; diff --git a/harness/apisupport.harness/windows-launcher-src/applauncher.h b/harness/apisupport.harness/windows-launcher-src/applauncher.h index b6002fd95b7b..0801c8a316c1 100644 --- a/harness/apisupport.harness/windows-launcher-src/applauncher.h +++ b/harness/apisupport.harness/windows-launcher-src/applauncher.h @@ -27,7 +27,7 @@ #include #include "shlobj.h" -#include "../ide/nblauncher.h" +#include "../../../nb/ide.launcher/windows/nblauncher.h" class AppLauncher : public NbLauncher { diff --git a/nb/ide.launcher/windows/Makefile.mingw b/nb/ide.launcher/windows/Makefile.mingw index 6db2f87fc281..9f5db6340940 100644 --- a/nb/ide.launcher/windows/Makefile.mingw +++ b/nb/ide.launcher/windows/Makefile.mingw @@ -15,8 +15,8 @@ # specific language governing permissions and limitations # under the License. -TMPFLD = ../../../../target/tmp/ -OFLD = ../../../../target/ide/ +TMPFLD = ./build/ +OFLD = ./build/ all: prepfolder netbeans64.exe netbeans.exe @@ -30,11 +30,11 @@ clean: netbeans64.res: netbeans.rc netbeans64.exe.manifest x86_64-w64-mingw32-windres -o$(TMPFLD)netbeans64.res -Ocoff -DMANIFEST_FILE=netbeans64.exe.manifest netbeans.rc -netbeans64.exe: netbeans.cpp nblauncher.cpp netbeans64.res ../bootstrap/utilsfuncs.cpp - x86_64-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec64.dll"' -DARCHITECTURE=64 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows netbeans.cpp nblauncher.cpp $(TMPFLD)netbeans64.res ../bootstrap/utilsfuncs.cpp -I ../bootstrap/ -o$(OFLD)netbeans64.exe -static -lstdc++ -static-libstdc++ -static-libgcc +netbeans64.exe: netbeans.cpp nblauncher.cpp netbeans64.res ../../../platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp + x86_64-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec64.dll"' -DARCHITECTURE=64 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows netbeans.cpp nblauncher.cpp $(TMPFLD)netbeans64.res ../../../platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp -I ../../../platform/o.n.bootstrap/launcher/windows/ -o$(OFLD)netbeans64.exe -static -lstdc++ -static-libstdc++ -static-libgcc netbeans.res: netbeans.rc netbeans.exe.manifest i686-w64-mingw32-windres -o$(TMPFLD)netbeans.res -Ocoff -DMANIFEST_FILE=netbeans.exe.manifest netbeans.rc -netbeans.exe: netbeans.cpp nblauncher.cpp netbeans.res ../bootstrap/utilsfuncs.cpp - i686-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec.dll"' -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows netbeans.cpp nblauncher.cpp $(TMPFLD)netbeans.res ../bootstrap/utilsfuncs.cpp -I ../bootstrap/ -o$(OFLD)netbeans.exe -static -lstdc++ -static-libstdc++ -static-libgcc +netbeans.exe: netbeans.cpp nblauncher.cpp netbeans.res ../../../platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp + i686-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec.dll"' -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows netbeans.cpp nblauncher.cpp $(TMPFLD)netbeans.res ../../../platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp -I ../../../platform/o.n.bootstrap/launcher/windows/ -o$(OFLD)netbeans.exe -static -lstdc++ -static-libstdc++ -static-libgcc diff --git a/nb/ide.launcher/windows/nblauncher.cpp b/nb/ide.launcher/windows/nblauncher.cpp index 393e2cd81a27..743b078507db 100644 --- a/nb/ide.launcher/windows/nblauncher.cpp +++ b/nb/ide.launcher/windows/nblauncher.cpp @@ -27,9 +27,9 @@ #include #include #include "nblauncher.h" -#include "../bootstrap/utilsfuncs.h" -#include "../bootstrap/argnames.h" -#include "../bootstrap/nbexecloader.h" +#include "../../../platform/o.n.bootstrap/launcher/windows/utilsfuncs.h" +#include "../../../platform/o.n.bootstrap/launcher/windows/argnames.h" +#include "../../../platform/o.n.bootstrap/launcher/windows/nbexecloader.h" using namespace std; diff --git a/nb/ide.launcher/windows/netbeans.exe.manifest b/nb/ide.launcher/windows/netbeans.exe.manifest index 2dda7fb5081b..62225b2083d1 100644 --- a/nb/ide.launcher/windows/netbeans.exe.manifest +++ b/nb/ide.launcher/windows/netbeans.exe.manifest @@ -20,7 +20,7 @@ --> - diff --git a/nb/ide.launcher/windows/netbeans64.exe.manifest b/nb/ide.launcher/windows/netbeans64.exe.manifest index b1d9a5f31d98..16ce76e4c917 100644 --- a/nb/ide.launcher/windows/netbeans64.exe.manifest +++ b/nb/ide.launcher/windows/netbeans64.exe.manifest @@ -22,7 +22,7 @@ - diff --git a/nb/ide.launcher/windows/version.h b/nb/ide.launcher/windows/version.h index b1667b9caf7c..ad20a7537198 100644 --- a/nb/ide.launcher/windows/version.h +++ b/nb/ide.launcher/windows/version.h @@ -18,11 +18,11 @@ */ #define COMPANY "" -#define COMPONENT "NetBeans IDE" -#define VER "12.5.0.0" -#define FVER 12,5,0,0 -#define BUILD_ID "28062021" +#define COMPONENT "Apache NetBeans IDE Launcher" +#define VER "101.1.0.0" +#define FVER 101,1,0,0 +#define BUILD_ID "101100" #define INTERNAL_NAME "netbeans" #define COPYRIGHT "Based on Apache NetBeans from the Apache Software Foundation and is licensed under Apache License Version 2.0" -#define NAME "NetBeans IDE 12.5" +#define NAME "Apache NetBeans IDE Launcher" diff --git a/platform/o.n.bootstrap/launcher/windows/Makefile.mingw b/platform/o.n.bootstrap/launcher/windows/Makefile.mingw index 0fd8e394f75c..feaaec349ac1 100644 --- a/platform/o.n.bootstrap/launcher/windows/Makefile.mingw +++ b/platform/o.n.bootstrap/launcher/windows/Makefile.mingw @@ -15,8 +15,8 @@ # specific language governing permissions and limitations # under the License. -TMPFLD = ../../../../target/tmp/ -OFLD = ../../../../target/bootstrap/ +TMPFLD = ./build/ +OFLD = ./build/ all: prepfolder nbexec64.dll nbexec64.exe nbexec.dll nbexec.exe diff --git a/platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest b/platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest index 580bb41e424e..5f5d7e229bfc 100644 --- a/platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest +++ b/platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest @@ -20,7 +20,7 @@ --> - diff --git a/platform/o.n.bootstrap/launcher/windows/version.h b/platform/o.n.bootstrap/launcher/windows/version.h index 26b4461403ba..1639c7836c80 100644 --- a/platform/o.n.bootstrap/launcher/windows/version.h +++ b/platform/o.n.bootstrap/launcher/windows/version.h @@ -18,11 +18,11 @@ */ #define COMPANY "" -#define COMPONENT "NetBeans Platform Launcher" -#define VER "12.5.0.0" -#define FVER 12,5,0,0 -#define BUILD_ID "28062021" +#define COMPONENT "Apache NetBeans Platform Launcher" +#define VER "101.1.0.0" +#define FVER 101,1,0,0 +#define BUILD_ID "101100" #define INTERNAL_NAME "nbexec" #define COPYRIGHT "Based on Apache NetBeans from the Apache Software Foundation and is licensed under Apache License Version 2.0" -#define NAME "NetBeans Platform Launcher" +#define NAME "Apache NetBeans Platform Launcher"